The 10 Variations of Two Pointers for Interview Preparation

Hey everyone! While most people focus on learning complex algorithms like DP and graphs, they often overlook one of the simplest yet most powerful patterns - Two Pointers. This might be because it seems too basic, or people don't realize how versatile it is. However, mastering two pointers can help you solve 15-20% of all interview problems with elegant O(n) solutions. It's one of the highest ROI patterns you can learn! So let me show you why two pointers deserves way more respect than it gets.


Variation 1: Opposite Direction (Converging)

When to use: Sorted array, palindrome checking, pair sum problems

Movement: Start from both ends, move toward center

Template:

int left = 0, right = arr.length - 1;
while (left < right) {
    // Process arr[left] and arr[right]
    if (condition) {
        left++;
    } else {
        right--;
    }
}

Classic Problems:

  1. Two Sum II - Input Array Is Sorted
  2. Valid Palindrome
  3. Container With Most Water
  4. Reverse String
  5. Remove Duplicates from Sorted Array

Why it works: When array is sorted or has symmetric property, we can eliminate half the search space with each decision.


Variation 2: Same Direction (Fast & Slow)

When to use: Remove elements, in-place modifications, partitioning

Movement: Both move forward, one faster than the other

Template:

int slow = 0;
for (int fast = 0; fast < arr.length; fast++) {
    if (shouldKeep(arr[fast])) {
        arr[slow] = arr[fast];
        slow++;
    }
}
return slow; // new length

Classic Problems:

  1. Remove Element
  2. Move Zeroes
  3. Remove Duplicates from Sorted Array
  4. Squares of a Sorted Array

Why it works: Fast pointer explores, slow pointer maintains the valid portion.


Variation 3: Sliding Window

When to use: Subarray/substring with constraints, variable window size

Movement: Expand right, shrink left when condition violated

Template:

int left = 0, right = 0;
while (right < arr.length) {
    // Add arr[right] to window
    right++;
    
    while (windowInvalid) {
        // Remove arr[left] from window
        left++;
    }
    
    // Update result with current window
}

Classic Problems:

  1. Longest Substring Without Repeating Characters
  2. Minimum Size Subarray Sum
  3. Longest Substring with At Most K Distinct Characters

Why it works: Maintains a valid window by expanding and contracting dynamically.


Variation 4: Partitioning (Dutch National Flag)

When to use: Sort into groups, 3-way partitioning

Movement: Three pointers - low, mid, high

Template:

int low = 0, mid = 0, high = arr.length - 1;
while (mid <= high) {
    if (arr[mid] == 0) {
        swap(arr, low, mid);
        low++;
        mid++;
    } else if (arr[mid] == 1) {
        mid++;
    } else {
        swap(arr, mid, high);
        high--;
    }
}

Classic Problems:

  1. Sort Colors
  2. Sort Array By Parity
  3. Partition Array

Why it works: Maintains three regions - processed, current, and unprocessed.


Variation 5: Merge Two Sorted Arrays

When to use: Merging sorted sequences, finding common elements

Movement: One pointer per array, advance smaller element

Template:

int i = 0, j = 0;
while (i < arr1.length && j < arr2.length) {
    if (arr1[i] < arr2[j]) {
        // Process arr1[i]
        i++;
    } else if (arr1[i] > arr2[j]) {
        // Process arr2[j]
        j++;
    } else {
        // Both equal
        i++;
        j++;
    }
}
// Handle remaining elements

Classic Problems:

  1. Merge Sorted Array
  2. Intersection of Two Arrays
  3. Intersection of Two Arrays II
  4. Median of Two Sorted Arrays

Why it works: Sorted property allows us to always know which element to process next.


Variation 6: Pair Sum (Multiple Pointers)

When to use: Finding pairs/triplets with target sum

Movement: Fix one, use two pointers for remaining

Template:

// For 3Sum
Arrays.sort(nums);
for (int i = 0; i < nums.length - 2; i++) {
    int left = i + 1, right = nums.length - 1;
    while (left < right) {
        int sum = nums[i] + nums[left] + nums[right];
        if (sum == target) {
            // Found triplet
            left++;
            right--;
        } else if (sum < target) {
            left++;
        } else {
            right--;
        }
    }
}

Classic Problems:

  1. 3Sum
  2. 3Sum Closest
  3. 4Sum
  4. Valid Triangle Number

Why it works: Sorted array + two pointers eliminates duplicate work.


Variation 7: Reverse/Rotate

When to use: In-place array/string reversal, rotation

Movement: Swap from both ends moving toward center

Template:

void reverse(int[] arr, int start, int end) {
    while (start < end) {
        swap(arr, start, end);
        start++;
        end--;
    }
}

// Rotate array: reverse(0, k-1), reverse(k, n-1), reverse(0, n-1)

Classic Problems:

  1. Reverse String
  2. Reverse Words in a String
  3. Rotate Array
  4. Reverse Vowels of a String

Why it works: Swapping from ends naturally reverses order.


Variation 8: Trapping Water / Histogram

When to use: Area/volume calculations, optimization problems

Movement: Two pointers with auxiliary variables tracking max/min

Template:

int left = 0, right = arr.length - 1;
int leftMax = 0, rightMax = 0, result = 0;

while (left < right) {
    if (arr[left] < arr[right]) {
        if (arr[left] >= leftMax) {
            leftMax = arr[left];
        } else {
            result += leftMax - arr[left];
        }
        left++;
    } else {
        if (arr[right] >= rightMax) {
            rightMax = arr[right];
        } else {
            result += rightMax - arr[right];
        }
        right--;
    }
}

Classic Problems:

  1. Trapping Rain Water
  2. Container With Most Water
  3. Largest Rectangle in Histogram (with stack)

Why it works: Process from both ends, always move the pointer with smaller value.


Variation 9: Subsequence Matching

When to use: Check if one sequence is subsequence of another

Movement: One pointer per string, advance first when match found

Template:

int i = 0; // pointer for subsequence
for (int j = 0; j < str.length() && i < subseq.length(); j++) {
    if (str.charAt(j) == subseq.charAt(i)) {
        i++;
    }
}
return i == subseq.length(); // all matched

Classic Problems:

  1. Is Subsequence
  2. Number of Matching Subsequences
  3. Shortest Way to Form String

Why it works: Greedily match characters in order they appear.


Variation 10: Interval Merging with Pointers

When to use: Merging overlapping intervals, range operations

Movement: Iterate with pointer, merge based on overlap

Template:

Arrays.sort(intervals, (a, b) -> a[0] - b[0]);
List<int[]> result = new ArrayList<>();
int[] current = intervals[0];

for (int i = 1; i < intervals.length; i++) {
    if (intervals[i][0] <= current[1]) {
        // Overlap - merge
        current[1] = Math.max(current[1], intervals[i][1]);
    } else {
        // No overlap
        result.add(current);
        current = intervals[i];
    }
}
result.add(current);

Classic Problems:

  1. Merge Intervals
  2. Insert Interval
  3. Remove Covered Intervals

Why it works: Sorted intervals allow sequential merging.


📊 Complete Problem List (By Difficulty)

  1. Two Sum II
  2. Valid Palindrome
  3. Remove Element
  4. Remove Duplicates from Sorted Array
  5. Reverse String
  6. Squares of a Sorted Array
  7. Move Zeroes
  8. Merge Sorted Array
  9. Is Subsequence
  10. Reverse Vowels of a String
  11. 3Sum
  12. Container With Most Water
  13. Sort Colors
  14. 3Sum Closest
  15. 4Sum
  16. Remove Duplicates from Sorted Array II
  17. Rotate Array
  18. Reverse Words in a String
  19. Partition Labels
  20. Valid Triangle Number
  21. Minimum Size Subarray Sum
  22. Number of Subsequences That Satisfy Sum Condition
  23. Trapping Rain Water
  24. Minimum Window Substring
  25. Substring with Concatenation of All Words
  26. Median of Two Sorted Arrays

Master two pointers, and you'll solve problems others struggle with using complex hash maps or nested loops - with cleaner code and better complexity!


Check out my posts which may help you in your preparation :

  1. 13 DP Patterns for Interview Preparation
  2. 10 Dijkstra Variations for Interview Preparation
  3. Understanding Time Complexity: The 10^8 Operations Rule
  4. 10 Essential Design Problems for DSA Interviews
  5. Essential CS Fundamental Topics For Interviews
  6. Essential Graph Patterns for Coding Interviews
  7. Essential String Patterns for Coding Interviews
  8. 15 Essential DSA Patterns for Tech Interviews

What's your favorite two pointer problem? Or which variation do you find trickiest? Let's discuss! 👇

Comments (4)