680. 验证回文字符串 Ⅱ
680. Valid Palindrome II
题目:
给定一个非空字符串 s
,最多删除一个字符。判断是否能成为回文字符串。
示例 1:
输入: “aba”
输出: True
示例 2:
输入: “abca”
输出: True
解释: 你可以删除c字符。
注意:
字符串只包含从 a-z 的小写字母。字符串的最大长度是50000。
题解:
建立两个索引,left
和right
,left
从左往右走,right
从右往左走,直到两个位置上的字符不同为止。如果两个索引能够相遇,表示原字符串是回文串,如果中途停止,再接着判断剩下的[left:right]
之间的子串是否可以删除端点left或者right后行成回文串。如果其中一个能形成回文串,返回True
,否则返回False
。
技巧:
建立两个索引,left
和right
.
C++
class Solution {
public:
bool validPalindrome(string s) {
int n = s.size();
int i = 0;//从左往右的索引
int j = n - 1;//从右往左的索引
while(i <= j && s[i] == s[j]){
i++;
j--;
}
if(i > j) {//索引相遇则表示原串是回文串
return true;
}
else{// 检测[left, right]之间的子串去掉left或者right能否形成回文串
string s1 = s.substr(i, j - i);
string s2 = s.substr(i+1, j - i);
return palindrome(s1) || palindrome(s2);
}
}
bool palindrome(string s){//回文串的判断
int i = 0;
int j = s.size() - 1;
while(i <= j && s[i] == s[j]){
i++;
j--;
}
return i > j;
}
};
Java
class Solution {
public boolean validPalindrome(String s) {
int n = s.length();
int left = 0, right = n - 1;
while(left < right && s.charAt(left) == s.charAt(right)) {//找左右第一次不同的字符
left++;
right--;
}
if(left >= right) {
return true;
}
//得到形如a****b的子串
String sub1 = s.substring(left, right);//检查a****是否是回文串
String sub2 = s.substring(left+1, right+1);//检查****b是否是回文串
return palindrome(sub1) || palindrome(sub2);
}
private boolean palindrome(String s) {
int n = s.length();
int left = 0, right = n - 1;
while(left < right && s.charAt(left) == s.charAt(right)) {
left++;
right--;
}
return left >= right ? true : false;
}
}
Python
class Solution(object):
def validPalindrome(self, s):
"""
:type s: str
:rtype: bool
"""
n = len(s)
i, j = 0, n - 1
while (i <= j and s[i] == s[j]): # 左右检测第一个不同的字符
i += 1
j -= 1
if i > j: # 原串是回文串
return True
# 得到形如a****b的子串
return self.palindrome(s[i:j]) or self.palindrome(s[i+1:j+1]) # 检查a****或者****b是否是回文串
def palindrome(self, s): # 检查回文串
n = len(s)
i, j = 0, n - 1
while(i <= j and s[i] == s[j]):
i += 1
j -= 1
if i > j:
return True
else:
return False