题目
给定一个非空字符串 s,最多删除一个字符。判断是否能成为回文字符串。
思路
1:暴力法
1)不删除字符,验证是否为回文
2)任意删除一个字符做判断,看是否为回文串,细节是实现字符数组的左移覆盖和判断是否为回文串
2:双指针判断,搞一个left指针和right指针,左指针和右指针一直判断是否指向的值相等,如果相等,left++,right–。如果不相等,则判断删除任意一个字符,是否为回文串,如果有一个为回文串,则表示可以为回文串,如果全部仍然不是回文串,则表示不能删除一个字符构成回文串。
代码-暴力法(超出时间限制)
bool isPalindrome(char* s,int len){
int left=0,right=len-1;
while(left<right){
if(s[left]==s[right]){
left++;
right--;
}
else
break;
}
if(left>=right) return true;
return false;
}
bool validPalindrome(char * s){
int len=strlen(s);
if(isPalindrome(s,len)){ //不删除字符就是回文串
return true;
}
char* nums=(char*) malloc(sizeof(char)* (len)); //在堆上分一个同样长度的数组
for(int i=0;i<len;i++){
nums[i]=s[i];
}
int new_len=len-1;
for(int j=1;j<len;j++){
for(int i=j;i<len;i++){
nums[i-1]=nums[i];
}
if(isPalindrome(nums,len-1)){
return true;
}
for(int k=0;k<len;k++){
nums[k]=s[k];
}
}
if(isPalindrome(s,len-1)) return true;
return false;
}
提交记录
384 / 460 个通过测试用例
状态:超出时间限制
代码-双指针判断
bool isPalindrome(char* s,int len){
int left=0,right=len-1;
while(left<right){
if(s[left]==s[right]){
left++;
right--;
}
else
break;
}
if(left>=right) return true;
return false;
}
bool validPalindrome(char * s){
int len=strlen(s);
int flag=0;
int left=0,right=len-1;
if(isPalindrome(s,len))
return true;
char* nums=(char*) malloc(sizeof(char) * len);
for(int i=0;i<len;i++){
nums[i]=s[i];
}
while(left<right){
if(s[left]==s[right]){
left++;
right--;
}
else{
for(int i=left;i<len-1;i++){ //left右边左移覆盖
nums[i]=nums[i+1];
}
if(isPalindrome(nums,len-1)){
flag=1;
break;
}
for(int i=0;i<len;i++){
nums[i]=s[i];
}
if(right==len-1){
if(isPalindrome(s,len-1)){
flag=1;
break;
}
}
for(int i=right;i<len-1;i++){
nums[i]=nums[i+1];
}
if(isPalindrome(nums,len-1)){
flag=1;
break;
}
break;
}
}
if(flag) return true;
return false;
}