Skip to content
article

Two pointers is not one trick. It is three shapes.

Opposite ends, read/write, and fast/slow. Learn to see which one the problem wants and half the array questions become boring.

Nikhil Sharan@nikhil_twopointers

May 9, 2026 · 4 min read

Every week someone messages me "bhaiya two pointers samajh aata hai but question mein apply nahi hota". That happens because people learn it as one trick. It is actually three different shapes, and the problem statement tells you which shape it wants if you read it slowly.

Shape 1: opposite ends, moving inward

Signal: the array is sorted (or you are allowed to sort it) and you want a pair with some property. Classic example: find two numbers in a sorted array that add up to target.

Brute force first, always. Two loops, check every pair. O(n²). For n = 10^5 that is 10^10 operations, TLE guaranteed.

Now the observation. If a[l] + a[r] is too small, moving r left can only make it smaller, so the only useful move is l++. If the sum is too big, the only useful move is r--. Every step throws away one element for good. That is why it is O(n).

int[] twoSum(int[] a, int target) {
    int l = 0, r = a.length - 1;
    while (l < r) {
        int sum = a[l] + a[r];
        if (sum == target) return new int[]{l, r};
        if (sum < target) l++;
        else r--;
    }
    return new int[]{-1, -1};
}

Let us dry run. a = [1, 3, 4, 6, 9], target = 10. l=0, r=4: 1 + 9 = 10, found. Change target to 7: 1 + 9 = 10 is too big, r=3. 1 + 6 = 7, found. Bas itna sa concept hai.

Same shape: container with most water, 3sum (fix one element, run two pointers on the rest), valid palindrome.

Shape 2: same direction, a slow writer and a fast reader

Signal: modify the array in place. Remove duplicates, move zeroes, partition, "keep the relative order". One pointer reads every element, the other points to where the next good element should be written.

int removeDuplicates(int[] a) {
    if (a.length == 0) return 0;
    int write = 1;
    for (int read = 1; read < a.length; read++) {
        if (a[read] != a[write - 1]) {
            a[write++] = a[read];
        }
    }
    return write;
}

Dry run on [1, 1, 2, 3, 3]. read=1 is a duplicate, skip. read=2 (value 2) differs from a[0], write it at index 1. read=3 (value 3) differs from a[1] = 2, write it at index 2. read=4 is a duplicate. Answer 3, and the array now starts with [1, 2, 3]. The reason this is safe: write never overtakes read, so you never overwrite something you still need.

Shape 3: fast and slow on a linked list

Signal: linked list, and the question is about a cycle, the middle, or the kth node from the end. Slow moves one step, fast moves two.

ListNode middle(ListNode head) {
    ListNode slow = head, fast = head;
    while (fast != null && fast.next != null) {
        slow = slow.next;
        fast = fast.next.next;
    }
    return slow;
}

When fast reaches the end, slow has covered half the distance. If there is a cycle, fast laps slow inside it and they meet (Floyd's algorithm). People memorise this one and forget why it works. Draw it on paper once with 6 nodes and you will never forget.

How to pick the shape in the interview

  • Sorted + pair or triplet → opposite ends
  • In place + "remove" / "move" / "keep relative order" → read/write
  • Linked list + cycle / middle / kth from end → fast/slow

Homework: solve 3 questions of each shape. Then come back after 4 days and solve them again without looking. The second attempt is where the learning happens. Ghabrao mat, for most people it clicks around question 7 or 8.

Time: O(n) for all three shapes. Space: O(1).

Written by

Nikhil Sharan

I teach DSA and system design on YouTube (Two Pointers, 1.2M). Ex-SDE at two product companies, now teaching full time. Dry run everything. No paid course here, only free stuff and honest opinions.

Get the best of #desi_devs weekly

One email each Monday with the most useful posts. No spam; unsubscribe in one click.

Comments

9

Sign in to join the conversation.

Sign in to comment
Rohit Verma@rohit_codes#1 in Desi Devs
bhai shape 2 wala read/write pointer mujhe 4 saal baad samajh aaya tha, jab production mein ek list in-place clean karni padi 😂 freshers ye post save karo
3 net votes
Sam Whitaker@segfault_sam3 rep in Desi Devs
fast and slow pointers is also how I find the middle of a meeting. when the PM starts repeating himself, we're halfway
1 net votes
Nikhil Sharan@nikhil_twopointers#3 in Desi Devs
😄 and if he repeats the same point twice, there is a cycle. Floyd would be proud.
2 net votes
Ayesha Siddiqui@laravel_ayesha5 rep in Desi Devs
Never thought of the read/write thing as two pointers. I have literally written that loop in PHP a hundred times for cleaning CSV imports. Sharing with my juniors, shukriya Nikhil
0 net votes
S. Ramanathan@ramanathan_retd3 rep in Desi Devs
In 1991 we called the read/write pattern "compaction" and did it on tape records. Nice to see it has a fashionable name now. Good explanation, the dry run is the right habit.
3 net votes
Nikhil Sharan@nikhil_twopointers#3 in Desi Devs
Sir, compaction on tape is a whole other level of in-place 🙏 Would love to read a post from you on that some day.
5 net votes
Karthikeyan S@karthik_embedded#10 in Desi Devs
Shape 2 is basically how we drop bad samples from a ring buffer in firmware without allocating anything. Zero extra memory, very embedded friendly. Good post
4 net votes
Kunal Bhatia@kunal_dsa#4 in Desi Devs
Found this through a junior who forwarded it to me. Nikhil bhai the "come back after 4 days and solve again" line is the whole secret honestly. I have a spreadsheet column just for revisits.
1 net votes
Nikhil Sharan@nikhil_twopointers#3 in Desi Devs
Kunal! Welcome here. Your spreadsheet is famous in my DMs, half my students want a copy.
0 net votes