一、題目描述
Given a non-empty string s, you may delete at most one character. Judge whether you can make it a palindrome.
Input: "abca"
Output: True
Explanation: You could delete the character 'c'.
二、題解
方法一:暴力(超時)
- 對於每一個位置 i 的字符我們都將其刪除,然後 check 是否是迴文串。
* 數據太大: s 的長度最大爲 50000, 的複雜度也就是運行 = 次。
public boolean validPalindrome(String s) {
int N = s.length();
StringBuilder sb = new StringBuilder(s);
for (int i = 0; i < N; i++) {
StringBuilder t = new StringBuilder(sb);
t.deleteCharAt(i);
if (check(t.toString())) {
return true;
}
}
return false;
}
public boolean check(String s){
int i = 0; int j = s.length()-1;
while(i < j){
if(s.charAt(i) != s.charAt(j)){
return false;
}
i++;
j--;
}
return true;
}
複雜度分析
- 時間複雜度:,
- 空間複雜度:,
方法二:雙指針
我們只想通過刪除一次字符,再驗證剩下的字符能不能組成迴文串。我們習慣用雙指針判斷迴文串。我們可以這樣去想:假如給定一個序列 s[l], s[l+1] ,..., s[r]
:
- 如果
s[l] = s[r]
,則需要再判斷s[l+1], s[l+1] ,..., s[r-1]
是否是迴文,直到l > r
爲止。 - 如果
s[l] != s[r]
,證明我可以刪除s[l]
和s[r]
其中之一來驗證刪除之後的串是否是迴文。我們將驗證這兩個序列:s[l+1], s[l+1] ,..., s[r]
s[l], s[l+1] ,..., s[r-1]
public boolean validPalindrome(String s) {
int l = 0, r = s.length()-1;
while (l < r) {
if (s.charAt(l) != s.charAt(r)) {
return check(s, l, r-1) || check(s, l+1, r);
}
l++; r--;
}
return true;
}
public boolean check(String s, int i, int j){
while(i < j){
if(s.charAt(i) != s.charAt(j)){
return false;
}
i++; j--;
}
return true;
}
複雜度分析
- 時間複雜度:,
- 空間複雜度:,