LeetCode / Classic Two Pointers Easy

Valid Palindrome

LC
Practice this algorithm on LeetCode to reinforce your understanding.
Open Problem

Read a string forwards and backwards at once: two pointers close in from both ends comparing characters — O(N) time, O(1) space

What does it solve?

Decide whether a string is a palindrome: it reads the same left-to-right and right-to-left. Place one pointer at the start and one at the end, compare, then step both inward.

Key insight: a palindrome mirrors around its center, so s[left] must equal s[right] at every step. The moment they differ, it can't be a palindrome, stop early. If the pointers cross without a clash, it is one. Each character is touched once → O(N), no extra memory.

The core idea

// converge from both ends
left = 0, right = n - 1
while left < right:
  if s[left] != s[right]:
    return false
  left++
  right--
return true

Complexity

Time complexity
O(N)

The two pointers together sweep the string once. At most N/2 comparisons before they meet in the middle.

Space complexity
O(1)

Only two index variables. No reversed copy, no extra buffer, the check happens in place.


Examples & edge cases

Live animation — two pointers converging from both ends
left pointer right pointer matched pair (settled) mismatch → not a palindrome center (pointers met)
String — comparing s[left] with s[right] —
Current comparison
left = — right = — compared = — verdict = —
Step — of —
left pointer
—
head
right pointer
—
tail
pairs checked
—
matched so far
Palindrome?
—
checking…
Select an example and press Play to start.
✓ Answer: —
Speed Medium

Step-by-step table

Step Phase left right s[left] s[right] Equal? Action Verdict

C++ implementation

valid_palindrome.cpp
#include <bits/stdc++.h>
using namespace std;

// True if s reads the same forwards and backwards
bool isPalindrome(string s) {
    int left = 0, right = (int)s.size() - 1;

    while (left < right) {
        if (s[left] != s[right])
            return false;   // mirror broken — stop early
        left++;
        right--;
    }
    return true;          // pointers crossed with no mismatch
}

// Variant: ignore case & non-alphanumerics (LeetCode 125)
bool isPalindromeClean(string s) {
    int l = 0, r = (int)s.size() - 1;
    while (l < r) {
        while (l < r && !isalnum(s[l])) l++;
        while (l < r && !isalnum(s[r])) r--;
        if (tolower(s[l]) != tolower(s[r])) return false;
        l++; r--;
    }
    return true;
}

int main() {
    cout << isPalindrome("racecar") << "\n"; // 1 (true)
    cout << isPalindrome("hello")   << "\n"; // 0 (false)
    return 0;
}

My Notes

📝 Notes ✅

▼