1. How would you check whether a string is a palindrome?
Determine whether a string reads the same forward and backward, including basic edge cases.
I would use two pointers, one at the start of the string and one at the end. While the left pointer is before the right pointer, I compare the two characters. If they are different, I return false immediately. If they match, I move both pointers inward. If the pointers meet or cross without finding a mismatch, I return true. This works because every mirrored pair must match. The time complexity is O(n), and the auxiliary space complexity is O(1).
See the Code while reading this explanation.
A palindrome is a string that reads the same from the beginning and the end. We need to return true when every character has the same character in its mirrored position. Otherwise, we return false. The two-pointer approach fits well because we can compare those mirrored characters directly. One pointer starts at the beginning and the other starts at the end. After a matching pair, both pointers move toward the middle. If any pair is different, we already know the string is not a palindrome and can stop immediately.
- Should the comparison be case-sensitive and use every character exactly as it appears?
- Should an empty string and a one-character string be considered palindromes?
The input is a string s. The output is a boolean. We return true if the string reads the same forward and backward. We return false if any mirrored pair of characters is different. The approved diagram uses exact character comparison, so the check is case-sensitive. For example, "Aa" returns false.
I use two integer indices called left and right. left starts at index
- right starts at s.length() -
- These pointers identify the next mirrored characters that still need to be checked. The central invariant is that every character outside the current [left, right] range has already matched its mirrored partner.
For the diagram's example s = "racecar", the indices are 0 through 6 and the characters are r, a, c, e, c, a, r. I set left = 0 and right = 6. Traversal starts at both ends, so the first comparison is the first r against the last r.
Step 1 starts with left = 0 and right = 6. We compare r with r. They match, so we move both pointers inward. The new state is left = 1 and right = 5, and processing continues.
Step 2 starts with left = 1 and right = 5. We compare a with a. They match, so we move inward again. The new state is left = 2 and right = 4, and processing continues.
Step 3 starts with left = 2 and right = 4. We compare c with c. They match, so the new state becomes left = 3 and right = 3.
At this point, left < right is false. No comparison is needed for the middle e because it is already at the same mirrored position. The loop stops and the method returns true.
Each successful comparison proves that one mirrored pair is equal. After that pair matches, moving both pointers inward is safe because that outer pair never needs to be checked again. If any pair is different, the string cannot read the same forward and backward, so returning false immediately is correct. If the pointers meet or cross without a mismatch, every required mirrored pair has matched, so the string is a palindrome.
The Java method initializes left and right at opposite ends of the string. The while loop runs only while left < right. Inside the loop, it compares s.charAt(left) with s.charAt(right). A mismatch returns false immediately. A match increments left and decrements right. When the pointers meet or cross, the loop finishes and the method returns true. The executable runner uses the exact diagram example, "racecar", and prints true.
The time complexity is O(n). We compare at most about half of the mirrored character pairs, which is still linear in the string length, and we can stop early on a mismatch. The auxiliary space complexity is O(1) because the algorithm stores only two integer indices. An empty string returns true because the loop never runs. A one-character string also returns true. An even-length palindrome such as "abba" returns true. Exact comparison is case-sensitive, so "Aa" returns false.
The key insight is that a palindrome is defined by matching mirrored character pairs. We do not need to create a reversed copy of the string. Instead, left starts at the first character and right starts at the last character. If s.charAt(left) and s.charAt(right) differ, we immediately know the answer is false. If they match, both pointers move inward. The invariant is that all character pairs outside the current [left, right] range have already matched. When the pointers meet or cross without a mismatch, every required pair has matched, so the answer is true.
public class Main {
static class Solution {
public boolean isPalindrome(String s) {
// Start one pointer at the first character.
int left = 0;
// Start the other pointer at the last character.
int right = s.length() - 1;
// Compare mirrored character pairs until the pointers meet or cross.
while (left < right) {
// A mismatch proves that the string cannot be a palindrome.
if (s.charAt(left) != s.charAt(right)) {
return false;
}
// This pair matched, so move both pointers to the next inner pair.
left++;
right--;
}
// Every required mirrored pair matched.
return true;
}
}
public static void main(String[] args) {
// Run the exact example shown in the approved diagram.
String s = "racecar";
Solution solution = new Solution();
// Expected output: true.
System.out.println(solution.isPalindrome(s));
}
}The time complexity is O(n), where n is the length of the string. The pointers move inward, so each mirrored character pair is checked at most once. The algorithm may also stop early when it finds a mismatch. The auxiliary space complexity is O(1). Auxiliary space means extra memory used by the algorithm. We only keep two integer indices, left and right, so the amount of extra memory does not grow with the input size.
The two-pointer pattern is useful when a problem can be checked from both ends at the same time. Palindrome checking is a direct example. The same pattern is also useful for comparing symmetric positions and for problems where moving inward from two boundaries reduces the remaining search area without needing extra storage.
This problem checks whether you can recognize the two-pointer pattern and turn it into simple, correct Java code. The interviewer can see whether you initialize the boundaries correctly, compare mirrored positions, move both pointers safely, and stop immediately on a mismatch. It also tests whether you can explain a useful invariant, handle basic cases such as empty and one-character strings, and give the correct O(n) time and O(1) auxiliary-space complexity.
A common mistake is moving only one pointer after the characters match. Both pointers must move inward. Another mistake is continuing after a mismatch instead of returning false immediately. Candidates may also use left <= right and perform an unnecessary comparison of the middle character with itself. Another mistake is changing the input by lowercasing it or removing characters even though this solution uses exact character comparison. Building a reversed copy is correct, but it uses O(n) extra space instead of the O(1) auxiliary space used by the two-pointer approach.
State the invariant before you code: every mirrored pair outside the current left and right pointers has already matched. Then put the mismatch check before moving the pointers. This makes both the correctness reasoning and the early return easy to explain.









