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,000s is made up of only lowercase English letters.Before attempting this problem, you should be comfortable with:
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.
true.i from 0 to n-1:i.true.false.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.
l at the start and r at the end of the string.l < r:s[l] == s[r], move both pointers inward (l++, r--).s[l+1...r] is a palindrome.s[l...r-1] is a palindrome.true if either substring is a palindrome.true.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.
isPalindrome(l, r) that checks if s[l...r] is a palindrome using two pointers without creating a new string.l = 0 and r = len(s) - 1.l < r:s[l] != s[r], return isPalindrome(l+1, r) or isPalindrome(l, r-1).l and decrement r.true if 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 TrueWhen 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.
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.