DSA & Algorithms
easy
mid
How would you check if a string is a palindrome without reversing it?
Use the two-pointer technique: one pointer from each end moving inward, comparing characters. O(n) time, O(1) space — no reversal, no extra allocation. Clarify whether to normalize case/whitespace/punctuation first.
4 min read·~10 min to think through
The constraint "without reversing" is pushing you toward the two-pointer technique — which is actually the better solution anyway (no extra allocation).
Two-pointer approach
js
function isPalindrome(str) {
let left = 0;
let right = str.length - 1;
while (left < right) {
if (str[left] !== str[right]) return false;
left++;
right--;
}
return true;
}- Compare the outermost pair, move inward. First mismatch → not a palindrome.
- Loop ends when the pointers meet (odd length: middle char ignored, correctly).
- O(n) time (really n/2 comparisons), O(1) space — beats the reverse-and-compare approach which allocates a whole new string.
Clarify the requirements first
Always ask: "raw characters, or normalized?" Common variant — ignore case, spaces, and punctuation ("A man, a plan, a canal: Panama"):
js
function isPalindrome(str) {
const s = str.toLowerCase().replace(/[^a-z0-9]/g, "");
let left = 0, right = s.length - 1;
while (left < right) {
if (s[left++] !== s[right--]) return false;
}
return true;
}Recursive variant (if they ask)
js
const isPal = (s, l = 0, r = s.length - 1) =>
l >= r ? true : s[l] !== s[r] ? false : isPal(s, l + 1, r - 1);Same O(n) time but O(n) call stack — worse than the loop for large inputs.
Edge cases
- Empty string / single char →
true(vacuously a palindrome). - Unicode —
str[i]indexes UTF-16 code units, so emoji/surrogate pairs break it; use[...str]to split into code points if Unicode matters. - Whitespace/case — depends entirely on the spec; ask.
What interviewers want
Reach for two pointers immediately, state O(n)/O(1), and ask the normalization question before coding — that clarification is itself a signal.
Follow-up questions
- •Why is two-pointer better than reverse-and-compare?
- •How would you handle the 'ignore punctuation and case' variant?
- •What's the tradeoff of the recursive version?
- •How does this break on emoji / Unicode, and how do you fix it?
Common mistakes
- •Reversing the string anyway (the prompt explicitly forbids it) — and allocating extra memory.
- •Not clarifying whether to normalize case/whitespace/punctuation.
- •Off-by-one in the pointer loop condition.
- •Indexing with [i] and breaking on surrogate pairs.
Performance considerations
- •Two-pointer is O(n) time, O(1) space — strictly better than building a reversed string (O(n) extra space). Recursion is O(n) time but O(n) stack.
Edge cases
- •Empty string and single character → true.
- •Mixed case / punctuation when normalization is expected.
- •Unicode characters and emoji.
- •Strings with only whitespace.
Real-world examples
- •Input validation, simple string-symmetry checks, a warm-up before harder palindrome problems (longest palindromic substring).
Senior engineer discussion
Seniors go straight to two pointers, state O(n)/O(1), and proactively ask the normalization question before writing code. They mention the Unicode indexing pitfall and note that the recursive form trades O(1) space for O(n) stack.
Related questions
DSA & Algorithms
Easy
4 min
JavaScript
Easy
4 min