680. Valid Palindrome II - Explanation
Description
You are given a string s, return true if the s can be a palindrome after deleting at most one character from it.
A palindrome is a string that reads the same forward and backward.
Note: Alphanumeric characters consist of letters (A-Z, a-z) and numbers (0-9).
Example 1:
Input: s = "aca"
Output: trueExplanation: "aca" is already a palindrome.
Example 2:
Input: s = "abbadc"
Output: falseExplanation: "abbadc" is not a palindrome and can't be made a palindrome after deleting at most one character.
Example 3:
Input: s = "abbda"
Output: trueExplanation: "We can delete the character 'd'.
Constraints:
1 <= s.length <= 100,000sis made up of only lowercase English letters.
Topics
Prerequisites
Before attempting this problem, you should be comfortable with:
- Two Pointers Technique - Using pointers from both ends of a string to compare characters
- Palindrome Fundamentals - Understanding how to check if a string reads the same forwards and backwards
1. Brute Force
Intuition
The simplest approach is to check every possibility. First, check if the string is already a palindrome. If not, try removing each character one at a time and check if the resulting string becomes a palindrome. If any removal produces a palindrome, return true. This guarantees we find a solution if one exists, but it requires checking up to n different strings.
Algorithm
- First check if the original string is a palindrome by comparing it to its reverse. If yes, return
true. - For each index
ifrom0ton-1:- Create a new string by removing the character at index
i. - Check if this new string is a palindrome.
- If it is, return
true.
- Create a new string by removing the character at index
- If no single removal produces a palindrome, return
false.
Time & Space Complexity
- Time complexity:
- Space complexity:
2. Two Pointers
Intuition
Instead of blindly trying every removal, we can be smarter. Use two pointers starting from both ends of the string and move them inward. As long as characters match, keep going. When we find a mismatch, we know exactly where the problem is. At this point, we have only two choices: remove the left character or remove the right character. We check if either choice results in a palindrome for the remaining substring.
Algorithm
- Initialize two pointers:
lat the start andrat the end of the string. - While
l < r:- If
s[l] == s[r], move both pointers inward (l++,r--). - If they differ, we found the mismatch. Check two possibilities:
- Skip the left character and check if
s[l+1...r]is a palindrome. - Skip the right character and check if
s[l...r-1]is a palindrome.
- Skip the left character and check if
- Return
trueif either substring is a palindrome.
- If
- If the loop completes without mismatches, the string is already a palindrome. Return
true.
Time & Space Complexity
- Time complexity:
- Space complexity:
3. Two Pointers (Optimal)
Intuition
The previous two-pointer solution creates new substrings, which costs O(n) space. We can optimize this by passing index bounds to our palindrome check function instead of creating new strings. This way, we check the same characters without allocating extra memory. The logic remains identical: find the first mismatch, then verify if skipping either character leads to a valid palindrome.
Algorithm
- Create a helper function
isPalindrome(l, r)that checks ifs[l...r]is a palindrome using two pointers without creating a new string. - Initialize pointers
l = 0andr = len(s) - 1. - While
l < r:- If
s[l] != s[r], returnisPalindrome(l+1, r) or isPalindrome(l, r-1). - Otherwise, increment
land decrementr.
- If
- Return
trueif the loop completes (string is already a palindrome).
class Solution:
def validPalindrome(self, s: str) -> bool:
def is_palindrome(l, r):
while l < r:
if s[l] != s[r]:
return False
l += 1
r -= 1
return True
l, r = 0, len(s) - 1
while l < r:
if s[l] != s[r]:
return (is_palindrome(l + 1, r) or
is_palindrome(l, r - 1))
l += 1
r -= 1
return TrueTime & Space Complexity
- Time complexity:
- Space complexity:
Common Pitfalls
Only Trying One Deletion Option
When a mismatch is found at positions l and r, you must check both possibilities: removing the character at l or removing the character at r. A common mistake is only trying one option (like always removing the left character). Both substrings s[l+1...r] and s[l...r-1] must be checked, and the answer is true if either forms a palindrome.
Forgetting That Zero Deletions Is Valid
The problem asks if the string can become a palindrome by deleting at most one character. This includes deleting zero characters. If the original string is already a palindrome, the answer is true. Some solutions only consider the deletion case and forget to check if the string is already valid as-is.
Sign in to join the discussion