原題鏈接:https://leetcode-cn.com/problems/valid-palindrome-ii/
題目描述
給定一個非空字符串
s
,最多刪除一個字符。判斷是否能成爲迴文字符串。注意: 字符串只包含從
a-z
的小寫字母。字符串的最大長度是50000。
思路分析
這題是迴文判斷的一個變式題,主要還是考查對雙指針的理解。用
low
和high
分別指向字符串s
的首位和末尾,如果二者相等,則執行low++
,high--
;如果不相等,則需要分兩種情況:1)第
low + 1
位與第high
位相等,依次循環判斷,如果爲迴文字符串,則返回true
,否則返回false
,記爲usedLeft
;2)第
low
位與第high - 1
位相等,依次循環判斷,如果爲迴文字符串,則返回true
,否則返回false
,記爲usedRight
。最後,綜合不等情況判斷,只要不等情況1)和2)中有一個符合迴文字符串,那麼都應該返回
true
,即判斷條件應爲usedLeft||usedRight
;跳出循環如果還沒返回值,說明是標準的迴文串,應返回true
。做題過程中,對不等判斷很容易忽視情況1)和2)是或的關係判斷, 即忽略判斷兩邊都可以的情況(貪心算法思想)。如測試實例:
"aguokepatgbnvfqmgmlcupuufxoohdfpgjdmysgvhmvffcnqxjjxqncffvmhvgsymdjgpfdhooxfuupuculmgmqfvnbgtapekouga"
。
參考代碼
- 雙指針法,時間複雜度爲 ,空間複雜度爲 。
class Solution {
public boolean validPalindrome(String s) {
if (s == null || s.length() < 1) {
return false;
}
int low = 0, high = s.length() - 1;
while (low < high) {
if (s.charAt(low) == s.charAt(high)) {
low++;
high--;
continue;
}
int left = low + 1, right = high - 1;
boolean usedLeft = isPalindrome(s, left, high);
boolean usedRight = isPalindrome(s, low, right);
return usedLeft || usedRight;
}
return true;
}
private boolean isPalindrome(String s, int low, int high) {
while (low < high) {
if (s.charAt(low) != s.charAt(high)) {
return false;
}
low++;
high--;
}
return true;
}
}
運行結果如下: