一、题目描述
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, N 2 N^2 N2 的复杂度也就是运行 5000 0 2 50000^2 500002 = 250000 250000 250000 次。
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;
}
复杂度分析
- 时间复杂度: O ( N 2 ) O(N^2) O(N2),
- 空间复杂度: O ( n ) O(n) O(n),
方法二:双指针
我们只想通过删除一次字符,再验证剩下的字符能不能组成回文串。我们习惯用双指针判断回文串。我们可以这样去想:假如给定一个序列 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;
}
复杂度分析
- 时间复杂度: O ( n ) O(n) O(n),
- 空间复杂度: O ( 1 ) O(1) O(1),