Using the Two Pointer Technique
Tags: beginners, tutorial, codenewbie, computerscience
Published: 2020-08-15 16:41:12

---
title: Using the Two Pointer Technique
published: true
description: The **two pointer technique** is a near necessity in any software developer's toolkit, especially when it comes to technical interviews. In this guide, we'll cover the basics so that you know when and how to use this technique.
tags: beginners, tutorial, codenewbie, computerscience
cover_image: https://storage.googleapis.com/algodailyrandomassets/curriculum/arrays/two-pointer-1.png
canonical_url: https://algodaily.com/lessons/using-the-two-pointer-technique
---

## The Two Pointer Technique

The **two pointer technique** is a near necessity in any software developer's toolkit, especially when it comes to technical interviews. In this guide, we'll cover the basics so that you know when and how to use this technique.

<img src="https://storage.googleapis.com/algodailyrandomassets/curriculum/arrays/two-pointer-1.svg" class="img-fluid" />


_This lesson was originally published at [https://algodaily.com](https://algodaily.com/lessons/using-the-two-pointer-technique), where I maintain a technical interview course and write think-pieces for ambitious developers._

## What is the pattern?

The name `two pointers` does justice in this case, as it is exactly as it sounds. It's the use of two different pointers (usually to keep track of array or string indices) to solve a problem involving said indices with the benefit of saving time and space. See the below for the two pointers highlighted in yellow.

But what are `pointers`? In computer science, a `pointer` is a reference to an object. In many programming languages, that object stores a memory address of another value located in computer memory, or in some cases, that of memory-mapped computer hardware.

<img src="https://storage.googleapis.com/algodailyrandomassets/curriculum/arrays/two-pointer-2.svg" class="img-fluid" />


### When do we use it?

In many problems involving collections such as arrays or lists, we have to analyze each element of the collection compared to its other elements.

There are many approaches to solving problems like these. For example we usually start from the first index and iterate through the `data structure` one or more times depending on how we implement our code.

Sometimes we may even have to create an additional `data structure` depending on the problem's requirements. This approach might give us the correct result, but it likely won't give us the most space and time efficient result.

This is why the `two-pointer technique` is efficient. We are able to process two elements per loop instead of just one. Common patterns in the two-pointer approach entail:

1. Two pointers, each starting from the beginning and the end until they both meet.
2. One pointer moving at a slow pace, while the other pointer moves at twice the speed.

These patterns can be used for string or array questions. They can also be streamlined and made more efficient by iterating through two parts of an object simultaneously. You can see this in the [Two Sum problem](https://algodaily.com/challenges/two-sum) or [Reverse a String](https://algodaily.com/challenges/reverse-a-string) problems.




## Running through an example

One usage is while searching for pairs in an array. Let us consider [a practical example](https://algodaily.com/challenges/two-sum): assume that you have a sorted array `arr`.

You're tasked with figuring out the pair of elements where `arr[p]` + `arr[q]` add up to a certain number. (To try this problem out, check the [Two Sum](https://algodaily.com/challenges/two-sum) and [Sorted Two Sum](https://algodaily.com/challenges/sorted-two-sum) problems here.)

The brute force solution is to compare each element with every other number, but that's a time complexity of `O(n^2)`. We can do better!

So let's optimize. You need to identify the indices `pointer_one` and `pointer_two` whose values sum to the integer `target`.

Let's initialize two variables, `pointer_one` and `pointer_two`, and consider them as our two pointers.



```py
pointer_one = 0
pointer_two = len(arr)-1
```



Note that `len(arr)-1` helps to get the last index possible in an array.

Also observe that when we start, `pointer_one` points to the first element of the array, and `pointer_two` points to the last element.

This won't always be the case with this technique (we'll explore the [sliding window concept](https://algodaily.com/lessons/a-birds-eye-view-into-sliding-windows) later, which uses two pointers but have them move in a different direction). For our current purposes, it is more efficient to start wide, and iteratively narrow in (particularly if the array is sorted).



```py
def two_sum(arr, target):
    pointer_one = 0
    pointer_two = input.length - 1

    while pointer_one < pointer_two:
```


Since the array is already sorted, and we're looking to process an index at each iteration, we can use two pointers to process them faster. One pointer _starts from the beginning of the array_, and the other pointer _begins from the end of the array_, and then we add the values at these pointers.

Once we're set up, what we want to do is check if the current pointers already sum up to our target. This might happen if the correct ones are on the exact opposite ends of the array.

Here's what the check might look like:



```py
if sum == targetValue:
  return true
```


However, it likely will not be the target immediately. Thus, we apply this logic: if the sum of the values is less than the target value, we increment the left pointer (move your left pointer `pointer_one` one index rightwards).

And if the sum is higher than the target value, we decrement the right pointer (correct the position of your pointer `pointer_two` if necessary).



```py
elif sum < targetValue:
  pointer_one += 1
else:
  pointer_two -= 1
```



In other words, understand that if `arr[pointer_one]` < `target-arr[pointer_two]`, it means we should move forward on `pointer_one` to get closer to where we want to be in magnitude.

This is what it looks like all put together:



```py
def two_sum(arr, target):
    pointer_one = 0
    pointer_two = input.length - 1

    while pointer_one < pointer_two:
        sum = input[pointer_one] + input[pointer_two]

        if sum == targetValue:
            return true
        elif sum < targetValue:
            pointer_one += 1
        else:
            pointer_two -= 1

    return false
```



It's crucial to see that how both indices were moving in conjunction, and how they depend on each other.

We kept moving the pointers until we got the sum that matches the target value-- or until we reached the middle of the array, and no combinations were found.

The time complexity of this solution is `O(n)` and space complexity is `O(1)`, a significant improvement over our first implementation!

### Another Example

In addition, to the previous example, the two pointer technique can also involve the pattern of using a fast pointer and a slow pointer.



```java
Node fast = head, slow = head
```



One usage is through detecting cycles in a `linked list` data structure. For example, a cycle (when a node points back to a previous node) begins at the last node of the `linked list` in the example below.

<img src="https://storage.googleapis.com/algodailyrandomassets/curriculum/linked-lists/slow-and-fast-pointers-step-1.svg" class="img-fluid" />



```
1 -- > 2 --> 3 --> 4
             ^     |
             |     |
             <- - -

```

The idea is to move the fast pointer twice as quickly as the slow pointer so the distance between them increases by `1` at each step.

<img src="https://storage.googleapis.com/algodailyrandomassets/curriculum/linked-lists/slow-and-fast-pointers-step-2.svg" class="img-fluid" />



```java
while(fast!=null && fast.next!=null){
  slow = slow.next;

  fast = fast.next.next;
```



However, if at some point both pointers meet, then we have found a cycle in the linked list. Otherwise we'll have have reached the end of the list and no cycle is present.

<img src="https://storage.googleapis.com/algodailyrandomassets/curriculum/linked-lists/slow-and-fast-pointers-step-3.svg" class="img-fluid" />



```java
if (slow==fast) return true;

```



The attached code is what the entire method would look like all together.

The time complexity would be `O(N)` or linear time.



```java
public static boolean detectCycle(Node head){
    Node fast = head, slow = head;

    while(fast!=null && fast.next!=null){
        slow = slow.next;

        fast = fast.next.next;

        if(slow==fast) return true;

    }
    return false;
}
```