Palindrome String
A string is a palindrome when it reads the same from left to right as from right to left, like level. Write a function that gets a string s of lowercase English letters and returns true if s is a palindrome and false otherwise.
Function
- sstring
- the lowercase string to check
- Returnsboolean
- true when s reads the same in both directions
Constraints
1 ≤ s.length ≤ 5 × 104scontains only lowercase English letters (atoz).
Examples
- Input
- s = "racecar"
- Output
- true
- Explanation
- Compare from the outside in:
rwithr,awitha,cwithc. The middleehas no partner and needs none, so the answer istrue.
- Input
- s = "abba"
- Output
- true
- Explanation
- With an even length every letter has a partner: the two
as match and the twobs match, so the answer istrue.
- Input
- s = "coddy"
- Output
- false
- Explanation
- The first letter
cand the last letteryalready differ, socoddyis not a palindrome and the answer isfalse.
Follow-up
How would you change the two pointers to skip spaces and punctuation and ignore case, so that Was it a car or a cat I saw counts as a palindrome?
Hints
Open them one at a time. Each one gives away a little more.
If
sis a palindrome, which character must its first character be equal to?The character at index
imust equal the one at indexn-1-i. Each such pair only needs to be checked once, so half of the indexes are enough.Put one index at the start and one at the end. Compare the two characters, return
falseon a mismatch, and move both indexes one step inward until they meet.
Solution
A palindrome equals its own reverse, so you can build the reverse and compare. You do not need the copy: the first character must match the last, the second the second to last, and so on. Two indexes walking inward test those pairs in place and stop at the first mismatch.
Compare the string with its reverse
Intuition
Reverse s and compare: racecar reversed is racecar, and coddy reversed is yddoc. A string reads the same both ways exactly when it equals its reverse.
The time is O(n), but the reversed copy is O(n) extra space, 50,000 characters at n = 5 × 10^4. The work is also always full: coddy is decided by its first and last letters, yet all five get reversed first.
Algorithm
- Build the reverse of
s, with the language's reverse function or a loop from the last character to the first. - Compare the reverse with
s. - Return
trueif they are equal andfalseotherwise.
def isPalindrome(s):
return s == s[::-1]Two pointers from both ends
Intuition
Reversing moves index i to index n-1-i, so s equals its reverse exactly when s[i] equals s[n-1-i] for every i. Each pair appears twice in that condition, so checking the left half is enough. In racecar the pairs are (0, 6), (1, 5) and (2, 4); the middle e at index 3 needs no partner.
The first pair that differs proves the answer is false, so coddy is decided after one comparison. At most n / 2 comparisons run, O(n) time, and two indexes are O(1) space. R first reads the string as a vector of character codes, which costs O(n).
Algorithm
- Set
left = 0andright = n-1. - While
left < right, compares[left]withs[right]. - If they differ, return
false. - Otherwise add 1 to
left, subtract 1 fromrightand repeat. - When the pointers meet or cross, every pair matched: return
true.
def isPalindrome(s):
left, right = 0, len(s) - 1
while left < right:
if s[left] != s[right]:
return False
left += 1
right -= 1
return True
Pitfalls and edge cases
- Returning
trueas soon as one pair matches.abcapasses its outer pair and fails the inner one, sotruecomes only after the loop. - Starting
rightatninstead ofn-1, which reads past the end (in C, the terminating'\0'). In Lua and R indexes run from 1 ton, so thererightdoes start atn. - Comparing strings with
==in C.reversed == scompares two pointers and is false for a copy; usestrcmp. - Building the reverse with
result = result + ch. Each step copies the string so far: about1.25 × 10^9character copies for 50,000 letters. - Indexing a Swift string with an integer: it does not compile. Walk
s.utf8or copy the characters into an array.
Frequently asked questions4
How do you check if a string is a palindrome?
Compare the first character with the last, the second with the second to last, and so on toward the middle. If any pair differs, the string is not a palindrome. Two indexes that start at both ends and move inward do this in one pass.
Can you check a palindrome without extra memory?
Yes. The two pointer check reads the characters in place and stores two indexes, so it uses O(1) extra space. Comparing s with its reverse is shorter to write but builds a second string of n characters.
What is the time complexity of checking a palindrome string?
O(n) for a string of length n. The two pointer check makes at most n / 2 comparisons and stops at the first mismatch, so coddy takes one comparison.
Is a single character a palindrome?
Yes, it reads the same in both directions. In the two pointer loop left and right both start at index 0, the loop never runs, and the function returns true.
Similar problems
Problems that use the same ideas. Solving two or three of them is what makes a pattern stick.
def isPalindrome(s):
# Write code hereTest #1
Test #2
Test #3
Argument
s = "racecar"
Expected Output
true