🐍1.7Different Ways to Check for a Palindrome in Python
Different Ways to Check for a Palindrome in Python
Introduction
A palindrome is a word, phrase, number, or sequence that reads the same forward and backward, such as madam
, racecar
, or 12321
.
Checking for palindromes is a common problem in programming and can be solved in multiple ways. In this blog, we will explore different techniques to determine if a given string is a palindrome.
1. Using String Slicing ([::-1]
)
Code:
def is_palindrome_slicing(s):
return s == s[::-1] # Reverse the string and check equality
print(is_palindrome_slicing("madam")) # True
print(is_palindrome_slicing("hello")) # False
Logic Used:
s[::-1]
reverses the string.- If the reversed string is the same as the original, it's a palindrome.
Explanation:
- This is the easiest and most readable method.
- Time Complexity:
O(n)
, wheren
is the length of the string. - Space Complexity:
O(n)
, since a new reversed string is created.
2. Using a Two-Pointer Approach
Code:
def is_palindrome_two_pointer(s):
left, right = 0, len(s) - 1 # Initialize two pointers
while left < right:
if s[left] != s[right]: # Compare characters from both ends
return False # If mismatch found, not a palindrome
left += 1 # Move left pointer right
right -= 1 # Move right pointer left
return True # If no mismatches, it's a palindrome
print(is_palindrome_two_pointer("madam")) # True
print(is_palindrome_two_pointer("hello")) # False
Logic Used:
- Use two pointers: one at the beginning (
left
), and one at the end (right
). - Move both pointers inward while checking if characters match.
Explanation:
- Efficient as it avoids creating a new string.
- Time Complexity:
O(n)
, as each character is checked once. - Space Complexity:
O(1)
, since no extra space is used.
3. Using Recursion
Code:
def is_palindrome_recursive(s):
if len(s) <= 1: # Base case: A single character or empty string is always a palindrome
return True
if s[0] != s[-1]: # Compare first and last character
return False
return is_palindrome_recursive(s[1:-1]) # Recursive call with inner substring
print(is_palindrome_recursive("madam")) # True
print(is_palindrome_recursive("hello")) # False
Logic Used:
- Recursively compare the first and last characters.
- Reduce the string by removing first and last characters in each step.
Explanation:
- Base Case: When the string is of length 0 or 1, it's a palindrome.
- Time Complexity:
O(n)
. - Space Complexity:
O(n)
(due to recursive function calls).
4. Using reversed()
and join()
Code:
def is_palindrome_reversed(s):
return s == "".join(reversed(s)) # Reverse string and compare
print(is_palindrome_reversed("madam")) # True
print(is_palindrome_reversed("hello")) # False
Logic Used:
reversed(s)
creates an iterator for the reversed string."".join(reversed(s))
converts it back to a string.- Compare with the original string.
Explanation:
- Alternative way to reverse a string without slicing.
- Time Complexity:
O(n)
. - Space Complexity:
O(n)
.
5. Using collections.deque
(Optimal for Large Inputs)
Code:
from collections import deque
def is_palindrome_deque(s):
d = deque(s) # Convert string to deque for fast popping
while len(d) > 1:
if d.popleft() != d.pop(): # Compare first and last element
return False
return True
print(is_palindrome_deque("madam")) # True
print(is_palindrome_deque("hello")) # False
Logic Used:
deque
(double-ended queue) allows efficient removal from both ends.- Uses
popleft()
(remove first) andpop()
(remove last) for comparison.
Explanation:
- More efficient than slicing for large datasets.
- Time Complexity:
O(n)
. - Space Complexity:
O(1)
, as no extra string is created.
Comparison of Methods
Method | Logic Used | Time Complexity | Space Complexity |
---|---|---|---|
String Slicing ([::-1] ) |
Reverse string and compare | O(n) |
O(n) |
Two-Pointer Approach | Compare characters from both ends | O(n) |
O(1) |
Recursion | Reduce string size recursively | O(n) |
O(n) (stack memory) |
Using reversed() |
Reverse using reversed() iterator |
O(n) |
O(n) |
Using deque |
Efficient pop operations from both ends | O(n) |
O(1) |
Summary Table
Method | Code Snippet | Logic Used | Explanation |
---|---|---|---|
String Slicing ([::-1] ) |
return s == s[::-1] |
Reverse the string using slicing | Compares original and reversed string |
Two-Pointer Approach | while left < right: if s[left] != s[right]: return False |
Compare characters from both ends | Uses two pointers (left , right ) moving inward |
Recursion | if s[0] != s[-1]: return False; return is_palindrome(s[1:-1]) |
Recursively reduce the string | Calls function on substring without first and last characters |
Using reversed() |
return s == "".join(reversed(s)) |
Reverse using reversed() iterator |
Converts reversed iterator back to string and compares |
Using deque |
d = deque(s); while len(d) > 1: if d.popleft() != d.pop(): return False |
Use deque for fast removals |
Removes first and last characters efficiently for comparison |
Conclusion
Each method has its pros and cons:
- For small strings:
[::-1]
slicing is the easiest and most readable. - For large inputs: Two-pointer (
while left < right
) orcollections.deque
is more efficient. - For recursion lovers: The recursive approach is elegant but inefficient for deep recursion.
- For optimized performance:
deque
is the best for large datasets.
Which method do you prefer? Let me know in the comments! 🚀
Comments
Post a Comment