81. Palindrome Check
Given a string, write a Python program that determines whether it reads the same forward and backward. Explain how your solution handles an empty string, a single character, letter case, and the time and space complexity.
I would use two pointers. One starts at the beginning of the string, and the other starts at the end. First, I convert the string to lowercase so letter case does not affect the comparison. While left is before right, I compare the mirrored characters. If they differ, I return False immediately. Otherwise, I move both pointers inward. If the loop finishes, I return True. The time complexity is O(n). The complete Python implementation uses O(n) auxiliary space because lower() creates a new string.
See the Code while reading this explanation.
The problem asks us to decide whether a string reads the same forward and backward. The solution uses two pointers. One pointer starts at the first character, and the other starts at the last character. Before comparing them, the code converts the string to lowercase. This makes the check case-insensitive, so "Level" is treated as "level".
- What input sizes, value ranges, and edge cases should the solution handle?
- What output should be returned for empty, invalid, or duplicate input?
- Should I prioritize execution time or memory use, and may I use the standard library?
The input is one string. The function returns True when the string is a palindrome. It returns False when at least one pair of mirrored characters is different.
The solution treats uppercase and lowercase versions of the same letter as equal. For example, the input "Level" becomes "level" before the comparisons begin.
We use two integer pointers named left and right.
The left pointer starts at index 0. The right pointer starts at the last index, which is len(text) - 1.
The central invariant is that every mirrored pair outside the current left and right positions has already matched. When the current pair also matches, both pointers can safely move toward the center.
For the example input "Level", the normalized string is "level".
Its length is 5. The indices are 0, 1, 2, 3, and 4.
The characters are:
index 0 = "l" index 1 = "e" index 2 = "v" index 3 = "e" index 4 = "l"
We start with left = 0 and right = 4.
At step 1, the state is left = 0 and right = 4.
We compare text[0], which is "l", with text[4], which is also "l". The characters are equal. We move both pointers inward. The new state is left = 1 and right = 3.
At step 2, we compare text[1], which is "e", with text[3], which is also "e". The characters are equal. We move both pointers inward again. The new state is left = 2 and right = 2.
The loop condition is left < right. At this point, 2 < 2 is false, so the loop stops. The middle character does not need to be compared with itself.
No mismatch was found, so the function returns True.
A palindrome must have equal characters at mirrored positions. The first character must match the last character. The second character must match the second-last character, and so on.
If one mirrored pair is different, the string cannot read the same in both directions. Returning False immediately is therefore correct.
If every required mirrored pair matches until the pointers meet or cross, the whole string is a palindrome. Returning True is therefore correct.
The function first calls s.lower() and stores the new lowercase string in text.
It initializes left to 0 and right to len(text) - 1.
The while loop runs while left < right. Inside the loop, the code compares text[left] and text[right]. If they are different, it returns False immediately.
If they match, left increases by 1 and right decreases by 1. When the loop finishes without a mismatch, the function returns True.
The time complexity is O(n), where n is the string length. In the worst case, the algorithm checks all mirrored pairs until the pointers reach the center. The lowercase conversion also takes O(n) time.
The pointer logic itself uses O(1) extra space. However, the complete Python implementation uses O(n) auxiliary space because s.lower() creates a new string.
An empty string returns True because left starts at 0 and right starts at -1, so the loop never runs.
A one-character string returns True because left and right both point to index 0, so the loop never runs.
Different letter cases are handled by converting the input to lowercase.
A string such as "abc" returns False at the first comparison because "a" and "c" do not match.
The key insight is that a palindrome can be verified by comparing characters in mirrored positions. A two-pointer approach does this directly. The left pointer begins at the start, and the right pointer begins at the end. The invariant is that every mirrored pair outside the two pointers has already matched. If the current pair differs, the answer is False. If it matches, both pointers move inward. When the pointers meet or cross, every required pair has matched, so the answer is True. This avoids creating a reversed copy only for comparison, although the shown implementation still creates a lowercase copy for case-insensitive checking.
def is_palindrome(s: str) -> bool:
text = s.lower()
left = 0
right = len(text) - 1
while left < right:
if text[left] != text[right]:
return False
left += 1
right -= 1
return True
example = "Level"
print(is_palindrome(example))Let n be the number of characters in the input string. Calling lower() takes O(n) time. The two pointers then compare at most about half of the character pairs, which is also O(n) time. Therefore, the total time complexity is O(n). The two pointer variables use O(1) extra space. However, Python creates a new string when lower() is called, so the complete implementation uses O(n) auxiliary space. If the input were already normalized and no copy were created, the pointer algorithm alone would use O(1) auxiliary space.
This pattern is useful when values must be compared from opposite ends of a sequence. It appears in palindrome validation, symmetry checks, array pair problems, and some sorted-array problems where left and right boundaries move toward each other.
This question tests whether the candidate recognizes the two-pointer pattern and can apply it correctly to strings. It also checks loop boundaries, pointer movement, early return, case normalization, and edge-case reasoning. The interviewer wants to see whether the candidate can connect the code to a correctness invariant and explain complexity accurately, including the extra string created by Python's lower() method.
One mistake is comparing the original characters without normalizing letter case, which makes "Level" incorrectly return False. Another mistake is moving only one pointer or moving a pointer in the wrong direction. A candidate may also forget to return False immediately when a mismatch is found. Another common error is placing return True inside the loop, which may return before all mirrored pairs have been checked. It is also incorrect to claim that the complete shown implementation uses O(1) auxiliary space, because lower() creates a new string of length n.
Explain the invariant before writing the loop: every mirrored pair outside left and right has already matched. Then show that a mismatch returns False and a match moves both pointers inward.










