Data Structures and Algorithms — Two Pointers Technique

Firat Tonak
7 min readDec 24, 2022

--

Two-pointers is a technique to solve array or string algorithm problems. It reduces time complexity to O(n) if you keep the work inside.

Basically, there are two integer variables which they could be called i and j or left and right which move along a loop.

If you are able to use the two-pointers technique, your algorithm will have never more than O(n) because two-pointers will keep the work inside a loop. (However, sometimes the time complexity is O(m+n) but we will investigate it later)

You might use either a while loop or for loop to manage pointers.

The concept is;

There are two variables which are one of those starts at 0-index, and the other one starts either at the end of the array or at 0-index.

int left=0;
int right=s.Length-1; // or int right=0;

There is a while loop that iterates until either

One pointer is bigger than the other one

or

One of the pointers is less than and equal to the input array.

while(left < right) //  while(right <= nums.Length - 1)

The last part is you should put your logic in the while loop depending on your problem and manage your pointers

left++

right--

Both left++ and right --

The final code should be as below

int left=0;
int right=s.Length-1; // int right=0;

while(left < right) // while(right <= nums.Length - 1)
{
//your logic here

left++;
right--;
}

This concept has a time complexity of O(n) and a space complexity of O(1).

Reverse String

We will use the two-pointers technique and one of those will start at the 0-index and one of those will start at the last index of the array.

int left=0;
int right=s.Length-1;

Then we need a while loop to check each letter and swap them if necessary.

while(left < right)
{
char temp=s[left];
s[left] = s[right];
s[right]=temp;

left++;
right--;
}

The code should be as below

int left=0;
int right=s.Length-1;

while(left < right)
{
char temp=s[left];
s[left] = s[right];
s[right]=temp;

left++;
right--;
}

The code has a time complexity of O(n) and a space complexity of O(1).

Remove Duplicates from the Sorted Array

This problem could be solved using the two-pointers technique and the complexity will be O(n) because we will keep the solution in the while loop.

First, we need a counter and two variables in this problem to keep our process and calculate the indexes.

int left=0;
int right=0;
int counter=1;

The counter is starting at one because we get the first element of the array all the time

Second, we need a while loop to proceed with our algorithm

while(right <= nums.Length - 1)

Third, we implement our logic in the while loop

 if(nums[left] == nums[right]) // 1
{
right++;
}
else // 2
{
left++;
nums[left] = nums[right];
counter++;
}

When we look at the number 1;

We are checking the elements for left and right pointers and if they are equal then only we increase the right pointer because we use the right pointer as a runner and the left pointer as deciding the index.

When we look at the number 2,

if elements are not equal, swap them after the left is increased and increase the counter.

We increase the left pointer before swapping because we want to change the correct index. If you look at the number 1, you will see that we increase only the right pointer and keep the left stable when they are equal.

Lastly, return the counter.

return counter;

All code should be as below

if(nums.Length == 0) return 0;
int left=0;
int right=0;
int counter=1;

while(right <= nums.Length - 1)
{
if(nums[left] == nums[right])
{
right++;
}
else
{
left++;
nums[left] = nums[right];
counter++;
}
}
return counter;

Another concept is we have a loop and after the loop is done, we check two pointers to make sure they are exhausted.

Let’s check an example and understand the concept

Basically, we have been given two sorted arrays and we need to combine them into one array and they have to be sorted.

int[] array1 = { 1, 4, 7 };
int[] array2 = { 2, 3, 8, 9 };

We need a new array and two pointers to compare the elements of given arrays

int[] resultArray = new int[m+n];
int index = 0;

int i = 0;
int j = 0;

We need a while loop to check the arrays and sort them.

while (i < n && j < m)
{
if (arr1[i] < arr2[j])
{
resultArray[index++] = arr1[i++];
}
else
{
resultArray[index++] = arr2[j++];
}
}

In this concept, we need to make sure that all pointers have been exhausted.

while (i < n)
{
resultArray[index++] = arr1[i++];
}
while (j < m)
{
resultArray[index++] = arr2[j++];
}

It will have a time complexity of O(n+m) where n is the length of arr1 and m is the length of arr2 and the space complexity of O(n).

Code: https://github.com/frttnk/Two_Pointers_O-n-m-

Median of Two Sorted Arrays

This question could be solved in different ways but we will use two pointers.

I will sort the array using the previous concept

double result=0;
int n=nums1.Length;
int m=nums2.Length;
int[] resultArray=new int[n+m];
int index=0;

int i=0;
int j=0;

while(i<n&j<m)
{
if(nums1[i] < nums2[j])
{
resultArray[index++] = nums1[i++];
}
else
{
resultArray[index++] = nums2[j++];
}
}

while(i<n)
{
resultArray[index++] = nums1[i++];
}
while(j<m)
{
resultArray[index++] = nums2[j++];
}

The second part is totally math of calculating the median of an array

int length = m+n;
if(length % 2 ==1)
{
result=resultArray[length / 2];
}
else
{
result = ((double)resultArray[length / 2] + (double)resultArray[(length / 2)-1]) / 2;
}

return result;

The final code should be as below

double result=0;

int n=nums1.Length;
int m=nums2.Length;

int[] resultArray=new int[n+m];
int index=0;

int i=0;
int j=0;

while(i<n&j<m)
{
if(nums1[i] < nums2[j])
{
resultArray[index++] = nums1[i++];
}
else
{
resultArray[index++] = nums2[j++];
}
}

while(i<n)
{
resultArray[index++] = nums1[i++];
}
while(j<m)
{
resultArray[index++] = nums2[j++];
}

int length = m+n;
if(length % 2 ==1)
{
result=resultArray[length / 2];
}
else
{
result = ((double)resultArray[length / 2] + (double)resultArray[(length / 2)-1]) / 2;
}

return result;

This algorithm has a time complexity of O(n+m) where n is the length of nums1 and m is the length of nums2 and a space complexity of O(n).

Is Subsequence

We will solve the problem using the two-pointers technique and will be easy.

It says s has to be in t and they need to have the same sequence which is why we will create two variables one of them will store the index and the second one will check each letter of s.

After we are done with the loop, the left pointer has to be as same as the length of s.

If the left is not equal to the length of s it means s is not in t or the order is different.

int left=0;
int right=0;

while(left < s.Length && right < t.Length)
{
if(s[left] == t[right])
{
left++;
right++;
}
else
{
right++;
}
}

return left == s.Length;

This algorithm has a time complexity of O(n) and a space complexity of O(1).

Container With Most Water

The question wants us to find and return the maximum amount of water a container can store which is why first we need to calculate the maximum area and then get rid of the shorter line for each iteration. This is how we approach this question to be able to solve it.

We will use Two-Pointer Technique which is why we will create 2 variables which are left and right. Also, we need one more variable which is the max that will store the max value.

int max=0;
int left=0;
int right=height.Length-1;

The left will start at the 0-index, and the right will start at the last index of the height because the height array will be getting smaller for each iteration.

We need a while loop to check each item of the height array.

while(left < right)

Now, we are able to access the heights. Then we need to find the minimum height because we do not want to spill the water.

int min = Math.Min(height[left],height[right]);

After we find the min-height, we are ready to calculate the area

int maxArea = min * (right-left);

Then, we need to update our max variable to keep the maximum value.

max = Math.Max(max,maxArea);

The last process is that we need to check to see which one is shorter — left or right

if(height[left] <= height[right])
{
left++;
}
else
{
right--;
}

All code should be like this

public int MaxArea(int[] height) {

int max=0;
int left=0;
int right=height.Length-1;

while(left < right)
{
int min = Math.Min(height[left],height[right]);
int maxArea = min * (right-left);
max = Math.Max(max,maxArea);

if(height[left] <= height[right])
{
left++;
}
else
{
right--;
}
}
return max;
}

Time complexity is O(n) because we kept all work inside the loop. The space complexity is O(n).

I tried to explain how we use the two-pointers technique and how we implement it.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

Firat Tonak
Firat Tonak

Written by Firat Tonak

Seasoned Senior Full-Stack .NET Developer sharing hands-on experience and cutting-edge technologies in comprehensive Full-Stack development. #TechInsights

No responses yet

Write a response