力扣680. 验证回文字符串 Ⅱ---双指针查找(暴力法与贪心法)

680. 验证回文字符串 Ⅱ

给定一个非空字符串 s,最多删除一个字符。判断是否能成为回文字符串。

示例 1:

输入: “aba”
输出: True
示例 2:

输入: “abca”
输出: True
解释: 你可以删除c字符。

注意:
字符串只包含从 a-z 的小写字母。字符串的最大长度是50000

题解:

方法一:双指针搜索与暴力

因为题目为“最多删除一个”,所以我们可以先看一下一个不删除的情况的时,他是不是一个回文字符串。
若是直接返回1,不是的话开始进行“删除”的操作。
根据暴力法,不用思考太多,直接每一个字符我们都将他删除试一试,看一看有没有行的。遍历一遍后有行的则返回1,没有则返回0.

bool validPalindrome(char * s){
    
    
    int i=0,j=strlen(s)-1;
    while(i<=j)
    {
    
    
        if(s[i]==s[j])
        {
    
    
            i++;
            j--;
            continue;
        }
        break;
    }
    if(i>=j)
    {
    
    
        return 1;
    }
    for(int k=0;k<strlen(s);k++)
    {
    
    
        i=0,j=strlen(s)-1;
        while(i<=j)
        {
    
    
            if(i==k)
            {
    
    
                i++;
                continue;
            }
            if(j==k)
            {
    
    
                j--;
                continue;
            }
            if(s[i]==s[j])
            {
    
    
                i++;
                j--;
                continue;
            }
            break;
        }
        if(i>=j)
        {
    
    
            return 1;
        }
    }
    return 0;
}

但这样会超时。

方法二:双指针搜索+贪心算法

找准贪心策略
对于给定的一个字符串,我们可以先看一下其头部和尾部的元素是否一样,如果不一样的话,则我们首要修改的就是头部或者尾部中的一个,然后拿修改后的再进行比较,如果第一次修改后发现还是不能成为回文,则再返回第一次修改前的状态,修改另一个,再进行比对;
如果一样的话,则最外层的这两个起不到限制他成为“不是回文字符串”的作用了。所以我们可以只看里面的那些是不是回文字符串即可。

同理在我们“剥掉第一层”后,原先的第二个和倒数第二个元素成为了“最外层”的元素,所以对他们我们发现仍然满足前者的过程,所以依旧进行上述操作。
因此我们可以发现这其实是一种规律。

上代码:

bool validPalindrome(char * s){
    
    
    int i=0,j=strlen(s)-1;
    int k=0,temp1,temp2;//k作为修改次数的反映,temp1和2为储存原先的状态
    while(i<=j)
    {
    
    
        if(s[i]==s[j])//相当于“剥掉”无用的元素
        {
    
    
            i++;
            j--;
            continue;
        }
        else if(s[i]!=s[j]&&k==0)//第一次修改
        {
    
    
            temp1=i;//先把原状态储存起来
            temp2=j;
            i++;//相当于“删除”操作
            k++;
            continue;
        }
        else if(s[i]!=s[j]&&k==1)//第二次修改
        {
    
    
            i=temp1;//恢复原状态
            j=temp2;
            j--;
            k++;
            continue;
        }
        else if(s[i]!=s[j]&&k>1)//修改后还是成不了回文
        {
    
    
            return 0;
        }
    }
    return 1;    
}

猜你喜欢

转载自blog.csdn.net/xiangguang_fight/article/details/112325823
今日推荐