Palindrome Check
Problem
Write a function that determines whether or not a given a string of characters is a palindrome
A palindrome is defined as a string that is written the same forward as backward
Code
Python
- Solution 1
- Solution 2
- Solution 3
- Solution 4
JavaScript
- Solution 1
- Solution 2
- Solution 3
- Solution 4
TypeScript
- Solution 1
- Solution 2
- Solution 3
- Solution 4
Java
- Solution 1
- Solution 2
- Solution 3
- Solution 4
C++
- Solution 1
- Solution 2
- Solution 3
- Solution 4
Space-Time Complexity
- Solution 1
- Solution 2
- Solution 3
- Solution 4
Time | Space | |
---|---|---|
Worse | O(n2) | O(n) |
Where n is the length of the input string
When we build our reversed string and do reversedString += string[i]
, at each iteration in the for loop, we're rebuilding a new string. In most languages where strings are immutable, if you do new += string[i]
, adding a character to a string, you're actually re-creating the entire new
string, iterating through every character in new
, and adding string[i]
; This is an O(n)-time operation. Since we're performing an O(n)-time operation at each iteration in the for loop, this will turn our function into an O(n2)-time algorithm overall
Notes
solution 1
Create a new string that's going to be the reversed version of our input string, compare that new string with the input string, and see if they're equal to each other
To do this we'll create a variable called reversedString
, initialize it to the empty string, then iterate through the reversed version of our given string, meaning we'll start at the last index of our string and go all the way to index zero
At every point in the iteration, we'll build the reversedString
by adding the letter at index i
in the given string, reversedString += string[i]
Once we're done building the reversed string, we'll do the palindrome comparison by testing weather or not our given string is equal to the reversed string we just built, return string == reversedString
solution 2
Instead of creating a new string, let's just store everything in a list, an array, and at the end we join the list into one string and do the palindrome comparison
To do this instead of initializing reversedString
to an empty string, we'll initialize it to an empty list, an empty array, reversedChars
, and when we do our iteration backwards through the given string, instead of saying reversedString += string[i]
, we'll say reversedChars.append(string[i])
, or .push
or whatever it is in your language of choice. This will keep pushing our string letters into the array, and at the very end instead of returning reversedString == string[i]
we'll return "".join(reversedChars) == string
solution 3
This will be the recursive way to solve this problem, it won't be a better solution that solution 2, but it'll be a different approach
Notice that when you're looking at a string and you want to know if it's a palindrome, you basically ask if the first letter is equal to the last letter, and if the string in the middle, the substring, is a palindrome as well. By applying this logic and approaching the problem in this way, assuming we have an isPalindrome()
function, we can solve this problem recursively
In our calling function, isPalindrome()
apart from taking in a string we can also take in the first index that we're looking at in the recursive call, i
To dynamically calculate j
the last index that we're looking at, at each recurisve call we can say, j = len(string) - 1 - i
Our base case will be whenever we arrive at the middle of our string or we're past the middle point, we'll just return i >= j
. Otherwise, return true if the first letter is equal to the last letter, and isPalindrome()
called on the string in the middle is true, return string[i] == string[j] and isPalindrome(mid)
. We can show off our recursive skills and do both of these checks in one line, return True if i >= j else string[i] == string[j] and isPalindrome(string, i + 1)
solution 4
This solutiuon will involve an iterative approach. The idea is that we've come up with algorithms that take O(n)-time, and it's obvious that we're not going to do better than that. We have to iterate through our given string to determine if it's a palindrome. But, as we've seen in solution 3, we don't have to store a new string and use recursion that might end up using additional space
To do this we initialize two pointers, one at our first letter and another pointer at our last letter. We then compare both letters, and if they're equal to each other we keep moving towards the middle of the string, otherwise we don't have a palindrome and we return false. If the pointers overlap then we're done, return true
In the actual implementation we'll first initialize the left pointer at the first index, leftIdx = 0
, and initialize the right pointer at the last index, rightIdx = len(string) - 1
Then, while our left pointer comes before the right pointer, while leftIdx < rightIdx
, if the two letters at both pointers are not equal to each other, if string[leftIdx] != string[rightIdx]
, return false, return False
. Otherwise, if both letters are equal to each other, then increment the left pointer, leftIdx += 1
, and decrement the right pointer, rightIdx -= 1
Once you get to the point where both pointers point to the same letter, in an odd string, or are past each other, in an even string, then you're out of the while loop and you're dealing with a palindrom so you're officially done, return True