Today we are going to discuss a **trending Algorithm** that is used frequently for solving problems the “** Two Pointer Algorithm**“.

In this post, we will first understand the Two Pointer Algorithm and then we will solve 2-3 problems based on it and also discuss two-pointer

**. Also, I will give**

*time complexity***problems for practice**so that you can understand this Algorithm more clearly. So let’s start[Greedy Algorithm].

Table of Contents

**Technical Definition** **Of Two Pointer Algorithm**

**Two Pointer Technique** uses two-pointer in one loop over the given** **data structure. It is commonly used for solving array, string, linked list coding problems.

The main purpose of this algorithm is to reduce the complexity of **O(n^3) or O(n^2)** based solution to **Linear time solution**.

Common patterns in the **two-pointer algorithm **approach involve-

(i) **Two pointers** each starting from the beginning and the end until they both meet.

(ii) One pointer moves at a **slow pace** while the other pointer moves at a **faster pace**.

(iii) **Pointer-I** and **Pointer-II** from two sequences.

We will discuss **Questions** to discuss the following Patterns.[Merge Sort Algorithms][Bubble Sort Algorithm]

**Nth node from end of linked list**

Given a linked list consisting of **L** nodes and given a number **N**. The task is to find the **N**^{th} node from the end of the linked list.**Input:**

The first line of input contains the number of test cases T. For each test case, the first line of input contains the number of nodes in the linked list and the number N. The next line contains N nodes of the linked list.

Output:

For each test case, output the data of the node which is at Nth distance from the end or -1 in case the node doesn’t exist.

User Task:

The task is to complete the function getNthFromLast() which takes two arguments: reference to head and N and you need to return Nth from the end.

Expected Time Complexity: O(N).

Expected Auxiliary Space: O(1).

Constraints:

1 <= T <= 200

1 <= L <= 103

1 <= N <= 103

Example:

Input:

2

9 2

1 2 3 4 5 6 7 8 9

4 5

10 5 100 5

Output:

8

-1

Explanation:

Testcase 1: In the first example, there are 9 nodes in the linked list and we need to find the 2nd node from the end. 2nd node from the end is 8. **Testcase 2:** In the second example, there are 4 nodes in the linked list and we need to find 5th from the end. Since ‘n’ is more than the number of nodes in the linked list, the output is -1.

**Analysis of Problem Statement**

The problem seems simple and you might be thinking why the hell I am discussing this **Question**.

Yes, Problem Statement is simple and also the solution too but if I bring **one extra constraint** to this Question, then this problem becomes interesting.

And my **motive** to discuss any question is that you should learn **something** from it.

**Naive Solution**

I think **the **problem statement is clear. You have to find the nth node of the linked list from the end.

The solution is simple, just **count** the number of nodes present in the linked list in the first traversal and then find the **Nth node** from the end in the second traversal.

Let’s see it’s code,

```
int getNthFromLast(Node *head, int n)
{
Node *t = head,*t1 = head;
int k = 0;
while(t != NULL)
{
t=t->next;
k++;
}
if(k < n) return -1;
else
{
for(int i = 0; i < (k - n); i++)
{
t1 = t1->next;
}
return (t1->data);
}
}
```

I think the above code is simple and time complexity is also O(n) but what if I tell you that you have to find the nth node from the end in just one traversal.

I mean that in the above code you need two traversals to find the result, but can you find the result in just one traversal.

It is **highly recommended** to think of a way to approach this problem in only one traversal.

**Nth node from end in just One Traversal**

The logic behind this solution is based on Two Pointer Approach. Let’s understand it more clearly.

Let’s take an example,

And in the above, we have to find a 3rd node from the end.

Now in the previous approach, we were first traversing from 1st node to last node, and then we were coming back to find nth node from the end or (k-n)th node from the front in the second traversal.

**Do we need to go to the last node and come back again..??**

To understand it clearly, let’s do a bit of **Mathematics**.

Let’s assume there **is** a ‘k’ number of nodes with us. And we have to find the **nth node** from the **back**.

Now **nth** node from the back is actually **(k-n)th** node from the front.

Now let us understand one thing, We can achieve this by another process too.

In this algorithm, we will **declare** two-pointer both initialised to head initially. Now we will move Pointer 1 till Nth node. When Pointer 1 reaches the Nth node, at the same time we will move Pointer 2. We will move both the pointers simultaneously till Pointer 1 reaches the last position.

The distance travelled by both the pointer will be same after Pointer 1 crosses Nth node.

Now Total distance travelled by Pointer 1: K

Total distance travelled by Pointer 2 : (K – n)

Let us analyse how Pointer 2 travelled (K – n) distance from the front. How we are sure about it**?**

The reason behind is that when we started **Pointer 2** to move when **Pointer 1** was at position **N**. So after that distance travelled by **Pointer 1 is (K-n)** which is same as distance travelled by **Pointer 2** as well. But since **Pointer 2** started it’s a journey from starting point, that’s why total distance travelled by Pointer 2 is (K-n-0) which is **(K – n)** and the **node present at this position** is our resultant node.

Hope you understood the logic behind this Algorithm. This is one application of **Two Pointer Approach**.

Let’s see the code,

```
int getNthFromLast(Node *head, int n)
{
Node *ptr1 = head, *ptr2 = head;
for(int i=1; i <= n-1; i++){
ptr1 = ptr1->next;
if(ptr1 == NULL) return -1;
}
while(ptr1->next != NULL){
ptr2 = ptr2->next;
ptr1 = ptr1->next;
}
return ptr2->data;
}
```

In this way, we can find nth node from end in just one traversal. Now let’s move ahead to solve one more Question.

**Problem : Key Pair[Two Pointer Algorithm]**

Given an array **A** of **N** positive integers and another number **X**. Determine whether or not there exist two elements in A whose sum is exactly **X**.**Input:**

The first line of input contains an integer **T** denoting the number of test cases. The first line of each test case is N and X, N is the size of array. The second line of each test case contains N integers representing array elements A[i].**Output:**

Print “**Yes**” if there exist two elements in A whose sum is exactly X, else “**No**” (without quotes).**Constraints:**

1 ≤ T ≤ 100

01 ≤ N ≤ 10^{5}

1 ≤ A[i] ≤ 10^{5}**Example:Input:**

2

6 16

1 4 45 6 10 8

5 10

1 2 4 3 6

**Output:**

Yes

Yes

**Explanation:**

Testcases 1:10 and 6 are numbers making a pair whose sum is equal to 16.

Testcases 1:

**Naive Method**

Naive Method is to run two nested loops and find that if two numbers add up to the specific target or not. This process takes **O(n^2)** time complexity.

```
bool twoSum(vector<int>& nums, int target) {
for (int i = 0; i < nums.size(); i++)
{
for (int j = i+1; j < nums.size(); j++)
{
if (nums[i] + nums[j] == target) {
return true;
}
}
}
return false;
}
```

**Two Pointer Approach**

We can reduce the complexity to O(n) by **Two Pointer Approach**. Let’s see it.

Since Array is sorted, we can use two Pointer here. We will keep one pointer at the first element and second pointer at the last element.

Since Array is sorted, if sum of both the element if greater than target sum, we will update out second pointer or else we will update our first pointer.

Let’s see it’s code.

```
bool twoSum(vector<int>& nums, int target) {
int pointerOne = 0;
int pointerTwo = nums.size() - 1;
while (pointerOne < pointerTwo)
{
int sum = nums[pointerOne] + nums[pointerTwo];
if (sum == target) {
return true;
}
else if (sum < target) {
pointerOne++;
}
else {
pointerTwo--;
}
}
return false;
}
```

We will discuss more **Problems** wit*h*** Two pointer algorithm** in our next Post. Hope you understood the basics of Two Pointer Approach.

That’s all folks..!!!