Arrays & Strings · intermediate · ~15 min

The two-pointer technique

Maintain two indices/pointers into one structure to scan in O(n).

Overview

'Two-pointer' refers to several patterns where two indices coordinate over a single sequence. The three flavours: converging (left + right, walk inward), same-direction (slow + fast, run at different speeds), and sliding window (left + right, both move forward, the window grows and shrinks).

Why it matters

Many problems that look like they need O(n log n) sorting or O(n^2) nested loops collapse to O(n) with two pointers. Cleanest cases: palindrome, cycle detection in linked lists, longest substring without repeats.

Core concepts

Converging. Start at both ends, decide direction at each step. Used in palindrome, 2-sum on sorted array, container-with-most-water.

Slow/fast (Floyd's tortoise & hare). Detect cycles in linked structures; find the middle of a list in one pass.

Sliding window. Maintain an invariant ('window contains no repeated chars'); shrink from the left when the invariant breaks.

Pentester mindset. Two-pointer is the building block of every fast string-search and pattern-detect routine in defensive scanners (anti-malware regex engines, log filters).

Syntax notes

No special syntax — just two indices (size_t i, j;) and a loop.

Lesson

Two-pointer is a family of algorithms where two indices walk a structure at coordinated speeds. Examples: palindrome check (converge from both ends), slow/fast cycle detection (Floyd), sliding-window substring problems.

Code examples

int is_palindrome(const char *s){
    size_t i = 0, j = strlen(s);
    while (i < j) {
        if (s[i] != s[--j]) return 0;
        i++;
    }
    return 1;
}

Line by line

/* slow/fast cycle detect */
node_t *slow = head, *fast = head;
while (fast && fast->next){
    slow = slow->next;
    fast = fast->next->next;
    if (slow == fast) return 1;   /* cycle */
}
return 0;

Common mistakes

  • Off-by-one on the meet point.
  • Forgetting that converging pointers may cross.

Debugging tips

Print both pointers/indices on every iteration; off-by-one is almost always at the meet point.

Memory safety

Pointer-to-pointer arithmetic must stay in bounds. For linked-list cycle detection, both slow and fast must be non-NULL before stepping fast twice.

Real-world uses

Cycle detection in graphs, palindrome scanners, KMP-like pattern matchers, sliding-window log analysis, in-place array compaction.

Practice tasks

  1. Palindrome check. 2. Reverse an array in place. 3. Floyd's cycle detection in a linked list.

Summary

Two pointers, one structure, coordinated steps. Converging, slow/fast, sliding window — three flavours, many problems.

Practice with these exercises