LeetCode——680. 驗證迴文字符串 Ⅱ
題目
680.驗證迴文字符串 Ⅱ
給定一個非空字符串 s,最多刪除一個字符。判斷是否能成爲迴文字符串。
示例 1:
輸入: “aba”
輸出: True
示例 2:
輸入: “abca”
輸出: True
解釋: 你可以刪除c字符。
解析
用兩個指針,一個從頭,一個從尾遍歷字符串,如果一樣就繼續;不一樣,就先刪除左邊一個字符(左邊的指針往右移動一位),然後接着用指針循環移動遍歷,如果一旦發現不相等,就說明刪除左邊的字符不對,那就接着嘗試刪除右邊的一個字符(右邊的指針向左移動一位),然後接着用指針循環移動遍歷,如果一旦發現不相等,就說明刪除右邊的字符也不對,如果刪除兩邊的一個字符都不能成立,就說明不滿足題意,任意一邊刪除後成立,就說明滿足題意(通過判斷兩個標誌的||,任意一個爲true即可)
代碼
class Solution {
public boolean validPalindrome(String s) {
//定義兩個指針的起始位置
int left = 0;
int right = s.length()-1;
//開始循環判斷
while (left<right){
//如果字符串一直滿足迴文串
if (s.charAt(left) == s.charAt(right)){
left++;
right--;
}else{ //一旦發現不滿足迴文串了
//刪除左邊和右邊是否成功,默認爲true
boolean deleteLeftSuccess = true;
boolean deleteRightSuccess = true;
//先將左邊的指針右移一位(刪除左邊一個字符),接着遍歷判斷
for (int i = left+1,j = right; i < j; i++,j--) {
if (s.charAt(i) != s.charAt(j)){ //如果還是有不相等的
deleteLeftSuccess = false; //刪除左邊一個字符不成立
break; //直接跳出循環,接着嘗試刪除右邊一個字符
}
}
//如果刪除左邊一個字符失敗,嘗試將右邊的指針左移一位(刪除右邊一個字符)的方法
if (!deleteLeftSuccess){
for (int i = left,j = right-1; i < j; i++,j--) {
if (s.charAt(i) != s.charAt(j)){ //如果還是有不相等的
deleteRightSuccess = false; //刪除右邊一個字符不成立
break; //直接跳出循環
}
}
}
//返回是否滿足題意。這時候直接返回,不會走外層的while循環了
return deleteLeftSuccess||deleteRightSuccess;
}
}
//執行這條語句,說明沒有走else,肯定是滿足迴文串的
return true;
}
}
簡化一下,思路差不多
class Solution {
public boolean validPalindrome(String s) {
//定義兩個指針的起始位置
int left = 0;
int right = s.length()-1;
//刪除左邊和右邊是否使用過,默認爲false
boolean deleteLeft = false;
boolean deleteRight = false;
//開始循環判斷
while (left<right){
//如果字符串一直滿足迴文串
if (s.charAt(left) == s.charAt(right)){
left++;
right--;
}else{ //一旦發現不滿足迴文串了
//如果刪除左邊沒有嘗試過
if (!deleteLeft){
left++; //左指針右移(刪除左邊)
deleteLeft = true; //標記刪除左邊已經使用過了
}else if (!deleteRight){ //如果刪除左邊嘗試過了,就判斷刪除右邊是否嘗試過
left--; //注意這裏需要讓左指針回退
right--; //右指針左移(刪除右邊)
deleteRight = true; //標記刪除右邊已經使用過了
}else { //刪除左邊和右邊都嘗試過
return false; //兩邊刪除都不滿足,直接返回false
}
}
}
//執行這條語句,說明滿足題意,返回true
return true;
}
}