验证回文串 II
难度:
标签:
题目描述
代码结果
运行时间: 42 ms, 内存: 16.2 MB
/*
* Problem: Given a string s, determine if it can become a palindrome by removing at most one character.
*
* Approach:
* 1. Convert the string to a list of characters.
* 2. Use Java Stream to filter out the mismatched character.
* 3. Check if the resulting substring is a palindrome after removing the mismatched character.
*/
import java.util.stream.IntStream;
public class Solution {
public boolean validPalindrome(String s) {
int left = 0, right = s.length() - 1;
while (left < right) {
if (s.charAt(left) != s.charAt(right)) {
int finalLeft = left, finalRight = right;
return IntStream.range(0, 2).anyMatch(i -> isPalindrome(s, finalLeft + i, finalRight - (1 - i)));
}
left++;
right--;
}
return true;
}
private boolean isPalindrome(String s, int left, int right) {
return IntStream.range(left, (right + left + 1) / 2)
.allMatch(i -> s.charAt(i) == s.charAt(right - i + left));
}
}
解释
方法:
这个题解采用了双指针的思路。首先判断原字符串是否是回文串,如果是,直接返回 True。如果不是,则使用两个指针 left 和 right 分别指向字符串的首尾。当左右指针指向的字符相等时,同时向中间移动;当遇到不相等的字符时,尝试删除左指针或右指针指向的字符,判断删除后的子串是否是回文串。如果删除任意一个字符后可以形成回文串,则返回 True,否则返回 False。
时间复杂度:
O(n)
空间复杂度:
O(n)
代码细节讲解
🦆
在判断删除左指针或右指针指向的字符后,为何没有继续使用双指针方法检查剩余子串是否为回文?
▷🦆
如果字符串长度非常大,切片操作会对性能有什么影响?有没有更高效的方式来检查子串是否为回文?
▷🦆
当左右指针的字符不相等时,为什么选择两种可能(删除左指针或右指针指向的字符)都要检验,而不是只检查一种?
▷🦆
在双指针对比中,如果中间部分已经验证为非回文,是否还有必要继续检查删除一个字符后的情况?
▷相关问题
验证回文串
如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。
字母和数字都属于字母数字字符。
给你一个字符串 s
,如果它是 回文串 ,返回 true
;否则,返回 false
。
示例 1:
输入: s = "A man, a plan, a canal: Panama" 输出:true 解释:"amanaplanacanalpanama" 是回文串。
示例 2:
输入:s = "race a car" 输出:false 解释:"raceacar" 不是回文串。
示例 3:
输入:s = " " 输出:true 解释:在移除非字母数字字符之后,s 是一个空字符串 "" 。 由于空字符串正着反着读都一样,所以是回文串。
提示:
1 <= s.length <= 2 * 105
s
仅由可打印的 ASCII 字符组成