Code of the Day
AdvancedString Algorithms

Two-pointer on strings

Use two pointers moving inward from both ends, understand palindrome checking as the canonical example, and contrast with sliding window.

CS FundamentalsAdvanced6 min read
By the end of this lesson you will be able to:
  • Describe the two-pointer pattern (left at start, right at end, move inward)
  • Recognise palindrome checking and reverse-words as canonical examples
  • Contrast two-pointer (opposite ends) with sliding window (same direction)

A two-pointer technique places one pointer at the left end of a sequence and one at the right end, then moves them toward each other. The loop runs until the pointers meet or cross. Because each pointer travels at most n steps, the whole traversal is O(n) with O(1) extra space.

Palindrome check — the canonical example

A string is a palindrome if it reads the same forwards and backwards. Compare the characters at left and right; if they match, move both inward. If any pair mismatches, it is not a palindrome.

def is_palindrome(s):
    left, right = 0, len(s) - 1
    while left < right:
        if s[left] != s[right]:
            return False
        left += 1
        right -= 1
    return True

The real-world version is trickier: "A man, a plan, a canal: Panama" is a palindrome if you ignore spaces, punctuation, and case. Filter to alphanumeric characters and lowercase before comparing:

def is_palindrome_clean(s):
    chars = [c.lower() for c in s if c.isalnum()]
    left, right = 0, len(chars) - 1
    while left < right:
        if chars[left] != chars[right]:
            return False
        left += 1
        right -= 1
    return True

Reversing words in place

Two-pointer works on word boundaries too. To reverse a list of words in place:

  1. Reverse the whole list with two pointers.
  2. Each word is now in the right position but its characters are reversed — run a second two-pointer pass on each word to un-reverse them.
def reverse_words(words):
    left, right = 0, len(words) - 1
    while left < right:
        words[left], words[right] = words[right], words[left]
        left += 1
        right -= 1
    return words

# ["hello", "world"] → ["world", "hello"]

Two-pointer vs sliding window

Both patterns use two indices into the same array, which is why they are sometimes conflated. The distinction is in the direction of travel:

PatternDirectionTypical goal
Sliding windowBoth pointers left → rightLongest/shortest subarray satisfying a condition
Two-pointer (opposite ends)Pointers shrink toward centreSymmetry checks, pair-sum problems, reversals

Sliding window can be thought of as a two-pointer variant where the right pointer leads and the left pointer follows, both moving right. The classic "two-pointer" label usually implies one pointer starts at the left end and the other at the right end, moving inward. The boundary is informal — the key is understanding which pointer moves in which direction and why.

Where to go next

Next: hashing strings — use character frequency maps (via Counter and defaultdict) to check anagrams, group words, and understand the O(n) cost of Python string hashing.

Finished reading? Mark it complete to track your progress.

On this page