Valid Palindrome Two Pointer in DSA C++ - Time & Space Complexity
We want to know how the time needed to check if a string is a palindrome grows as the string gets longer.
Specifically, how the two-pointer method affects this time.
Analyze the time complexity of the following code snippet.
bool isPalindrome(string s) {
int left = 0, right = s.size() - 1;
while (left < right) {
if (!isalnum(s[left])) { left++; continue; }
if (!isalnum(s[right])) { right--; continue; }
if (tolower(s[left]) != tolower(s[right])) return false;
left++;
right--;
}
return true;
}
This code checks if a string is a palindrome by moving two pointers from both ends towards the center, skipping non-alphanumeric characters.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The while loop that moves two pointers through the string.
- How many times: At most once per character, so up to n times where n is the string length.
As the string gets longer, the number of steps grows roughly in direct proportion to its length.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 checks |
| 100 | About 100 checks |
| 1000 | About 1000 checks |
Pattern observation: The operations grow linearly with input size; doubling the string roughly doubles the work.
Time Complexity: O(n)
This means the time to check the palindrome grows in a straight line with the length of the string.
[X] Wrong: "Because there are two pointers, the time complexity is O(n²)."
[OK] Correct: Each pointer moves forward without going back, so together they only scan the string once, making it O(n), not squared.
Understanding this linear time check shows you can efficiently handle strings and use two-pointer techniques, a common skill in coding challenges.
"What if we did not skip non-alphanumeric characters and checked every character directly? How would the time complexity change?"
Practice
Solution
Step 1: Understand two-pointer approach
Two pointers start at the beginning and end of the string and move inward.Step 2: Compare characters at pointers
If characters differ, string is not palindrome; if all match, it is palindrome.Final Answer:
Use two pointers starting from both ends and move towards the center comparing characters -> Option BQuick Check:
Two-pointer technique = Use two pointers starting from both ends and move towards the center comparing characters [OK]
- Trying to sort string instead of comparing characters
- Only checking half the string without pointers
- Ignoring case or non-alphanumeric characters
s?Solution
Step 1: Identify valid pointer initialization
Left pointer starts at 0 (first char), right pointer at last index (size - 1).Step 2: Check each option
int left = 0, right = s.size() - 1; correctly sets left=0 and right=s.size()-1; others have invalid indices.Final Answer:
int left = 0, right = s.size() - 1; -> Option AQuick Check:
Pointers start at 0 and size-1 = int left = 0, right = s.size() - 1; [OK]
- Starting right pointer at s.size() (out of range)
- Swapping left and right initialization
- Starting left pointer at 1 instead of 0
std::string s = "A man, a plan, a canal: Panama";
int left = 0, right = s.size() - 1;
while (left < right) {
while (left < right && !std::isalnum(s[left])) left++;
while (left < right && !std::isalnum(s[right])) right--;
if (std::tolower(s[left]) != std::tolower(s[right])) {
std::cout << "Not Palindrome" << std::endl;
return 0;
}
left++;
right--;
}
std::cout << "Palindrome" << std::endl;Solution
Step 1: Understand the code logic
It skips non-alphanumeric chars and compares characters case-insensitively from both ends.Step 2: Check if string is palindrome ignoring cases and symbols
"A man, a plan, a canal: Panama" is a classic palindrome ignoring spaces and punctuation.Final Answer:
Palindrome -> Option DQuick Check:
Ignoring non-alnum and case, string is palindrome = Palindrome [OK]
- Not skipping non-alphanumeric characters
- Comparing characters case-sensitively
- Confusing output with runtime or compile errors
std::string s = "racecar";
int left = 0, right = s.size();
while (left < right) {
if (s[left] != s[right]) {
std::cout << "Not Palindrome" << std::endl;
break;
}
left++;
right--;
}
std::cout << "Palindrome" << std::endl;Solution
Step 1: Check pointer initialization
Right pointer is set to s.size(), which is one past the last valid index.Step 2: Understand consequences
Accessing s[right] causes out-of-bounds error or undefined behavior.Final Answer:
Right pointer initialized to s.size() which is out of range -> Option AQuick Check:
Right pointer must be s.size()-1, not s.size() [OK]
- Using s.size() as last index
- Ignoring out-of-bounds access errors
- Assuming loop condition fixes index error
s, how would you modify the two-pointer palindrome check to ignore spaces, punctuation, and be case-insensitive? Choose the best approach.Solution
Step 1: Handle non-alphanumeric characters
Skip spaces and punctuation by moving pointers until alphanumeric chars found.Step 2: Compare characters case-insensitively
Convert characters to lowercase before comparing to ignore case differences.Final Answer:
Use two pointers; skip non-alphanumeric chars; compare lowercase characters -> Option CQuick Check:
Skip non-alnum + lowercase compare = Use two pointers; skip non-alphanumeric chars; compare lowercase characters [OK]
- Comparing characters without skipping punctuation
- Ignoring case differences
- Using frequency count which doesn't check order
Ready to prove it?
Pass the test and this pattern moves unknown
