标签:联系 lan 指定 color turn 初始 深度 左右 删除
给定一个非空字符串?s,最多删除一个字符。判断是否能成为回文字符串。
示例 1:
输入: "aba"
输出: True
示例 2:
输入: "abca"
输出: True
解释: 你可以删除c字符。
注意:
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/valid-palindrome-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
至多删除一个,那么左右指针夹逼验证时有以下三种情况:
三种情况除了初始指针位置区别外验证的模式相同;
最多需要进行三次模式验证,但是三次模式验证的指针起始位置需要记录;
指定两个变量记录指针的位置:
算法复杂度:
首次验证为递归的第一层,删除左或右一个字符为递归的第二层,所以递归需要严格控制只递归到第二层,设计使用一个boolean变量控制;
详见代码;
算法复杂度:
在首次验证失败时,需要验证左删除或者右删除,这里的思路是,先尝试左删除,若左删除验证失败,则在当前指针位置基础上让左指针向左回退一个位置,右指针前左进一个位置再继续验证,平衡掉先删左时多右移动的距离;
算法复杂度:
package leetcode;
/**
* @author ZhouJie
* @date 2020年5月19日 上午12:24:57
* @Description: 680. 验证回文字符串 Ⅱ
*
*/
public class LeetCode_0680 {
}
class Solution_0680 {
/**
* @author: ZhouJie
* @date: 2020年5月19日 上午12:25:24
* @param: @param s
* @param: @return
* @return: boolean
* @Description: 1-两遍指针遍历,记录指针的位置,因为总共有三次机会去验证是否可改造成回文;
*
*/
private int start = 0;
private int end = 0;
public boolean validPalindrome_1(String s) {
end = s.length() - 1;
if (!check(s)) {
int ss = start, ee = end;
start++;
if (!check(s)) {
start = ss;
end = ee;
end--;
return check(s);
}
}
return true;
}
private boolean check(String s) {
if (start > end) {
return false;
} else {
while (start <= end) {
if (s.charAt(start) == s.charAt(end)) {
start++;
end--;
} else {
return false;
}
}
return true;
}
}
/**
* @author: ZhouJie
* @date: 2020年5月19日 上午12:52:52
* @param: @param s
* @param: @return
* @return: boolean
* @Description: 2-递归验证,控制只递归两层;
*
*/
public boolean validPalindrome_2(String s) {
return check(s, 0, s.length() - 1, true);
}
private boolean check(String s, int start, int end, boolean f) {
while (start < end) {
if (s.charAt(start) == s.charAt(end)) {
start++;
end--;
} else {
// 若是首次,则进行删除左或右再进行验证,否则说明无法改造为回文
return f && (check(s, start + 1, end, false) || check(s, start, end - 1, false));
}
}
return true;
}
/**
* @author: ZhouJie
* @date: 2020年5月19日 上午1:09:12
* @param: @param s
* @param: @return
* @return: boolean
* @Description: 3-单个方法内增加变量解决;
*
*/
public boolean validPalindrome_3(String s) {
int left = 0, right = s.length() - 1;
boolean leftDelete = true, rightDelete = true;
while (left < right) {
if (s.charAt(left) == s.charAt(right)) {
left++;
right--;
} else {
// 尝试删除左边
if (leftDelete) {
left++;
leftDelete = false;
// 尝试删除右边,此时左边要回退一个字符
} else if (rightDelete) {
left--;
right--;
rightDelete = false;
} else {
return false;
}
}
}
return true;
}
}
标签:联系 lan 指定 color turn 初始 深度 左右 删除
原文地址:https://www.cnblogs.com/izhoujie/p/12916339.html