Valid Palindrome Two Pointer in DSA Rust - Time & Space Complexity
We want to know how long it takes to check if a string is a palindrome using two pointers.
How does the time needed grow as the string gets longer?
Analyze the time complexity of the following code snippet.
fn is_palindrome(s: &str) -> bool {
let bytes = s.as_bytes();
let (mut left, mut right) = (0, bytes.len().saturating_sub(1));
while left < right {
if bytes[left] != bytes[right] {
return false;
}
left += 1;
right = right.saturating_sub(1);
}
true
}
This code checks if a string reads the same forwards and backwards by comparing characters from both ends moving towards the center.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Comparing characters at two positions in the string.
- How many times: Up to half the length of the string (n/2 times).
As the string gets longer, the number of comparisons grows roughly half as fast.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 5 comparisons |
| 100 | 50 comparisons |
| 1000 | 500 comparisons |
Pattern observation: The operations grow linearly with input size, but only half as many steps are needed.
Time Complexity: O(n)
This means the time to check grows directly in proportion to the string length.
[X] Wrong: "The time complexity is O(n²) because we compare pairs of characters."
[OK] Correct: Each comparison is done once per pair, and we only move inward, so total comparisons grow linearly, not quadratically.
Understanding this pattern helps you quickly analyze string problems and shows you can reason about efficient scanning techniques.
"What if we ignored non-alphanumeric characters and case differences? How would the time complexity change?"
Practice
Solution
Step 1: Understand two-pointer approach
The two-pointer technique uses one pointer at the start and one at the end of the string.Step 2: Compare characters moving inward
Both pointers move towards the center, comparing characters at each step to check equality.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]
- Thinking reversing string is the two-pointer method
- Checking character counts instead of positions
- Sorting string changes order, not palindrome check
s?Solution
Step 1: Identify pointer initialization for indices
Left pointer starts at 0 (first char), right pointer at last index (length - 1).Step 2: Check mutability and correct indices
Both pointers must be mutable to move; right pointer must be s.len() - 1 to avoid out-of-bounds.Final Answer:
let (mut left, mut right) = (0, s.len() - 1); -> Option AQuick Check:
Correct pointer init = let (mut left, mut right) = (0, s.len() - 1); [OK]
- Using s.len() as right index causes out-of-bounds
- Not making pointers mutable
- Starting left pointer at 1 skips first character
fn is_palindrome(s: &str) -> bool {
let bytes = s.as_bytes();
let (mut left, mut right) = (0, bytes.len() - 1);
while left < right {
if bytes[left] != bytes[right] {
return false;
}
left += 1;
right -= 1;
}
true
}
fn main() {
println!("{}", is_palindrome("racecar"));
println!("{}", is_palindrome("hello"));
}Solution
Step 1: Check palindrome for "racecar"
Characters match from both ends moving inward, so returns true.Step 2: Check palindrome for "hello"
Characters differ at first comparison ('h' vs 'o'), so returns false.Final Answer:
true\nfalse -> Option CQuick Check:
racecar = true, hello = false [OK]
- Assuming hello is palindrome
- Confusing output order
- Ignoring early return on mismatch
fn is_palindrome(s: &str) -> bool {
let bytes = s.as_bytes();
let (mut left, mut right) = (0, bytes.len());
while left < right {
if bytes[left] != bytes[right] {
return false;
}
left += 1;
right -= 1;
}
true
}Solution
Step 1: Identify out-of-bounds error
Right pointer is set to bytes.len(), which is out of valid index range (0 to len-1).Step 2: Fix pointer initialization
Set right to bytes.len() - 1 to point to last valid character index.Final Answer:
Change right initialization to bytes.len() - 1 -> Option AQuick Check:
Right pointer must be last index = Change right initialization to bytes.len() - 1 [OK]
- Using length as index causes panic
- Changing while condition without fixing index
- Making pointers immutable prevents movement
s = "A man, a plan, a canal: Panama", which Rust code modification correctly checks if s is a palindrome ignoring non-alphanumeric characters and case using two pointers?Solution
Step 1: Understand problem requirements
We must ignore non-alphanumeric characters and case differences when checking palindrome.Step 2: Apply two-pointer with skipping and case normalization
Move pointers inward, skip chars that are not letters or digits, compare lowercase versions of characters.Final Answer:
Use two pointers skipping non-alphanumeric chars and compare lowercase characters -> Option DQuick Check:
Skip non-alphanumeric + lowercase compare = Use two pointers skipping non-alphanumeric chars and compare lowercase characters [OK]
- Comparing with punctuation included
- Ignoring case differences
- Reversing string without filtering
Ready to prove it?
Pass the test and this pattern moves unknown
