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
left = 0, right = n - 1
while left < right:
if s[left] != s[right]:
return false
left++
right--
return true
Complexity
The two pointers together sweep the string once. At most N/2 comparisons before they meet in the middle.
Only two index variables. No reversed copy, no extra buffer, the check happens in place.
Examples & edge cases
Step-by-step table
| Step | Phase | left | right | s[left] | s[right] | Equal? | Action | Verdict |
|---|
C++ implementation
#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