【leetcode】-5-最长回文子串

【方法一:动态规划】

第一步:确定状态

如果一个子串是回文串,则在其首尾加上相同的字符仍然是回文串。

最后一步:当回文串两头加上不相同的字符时,回文串长度不会增加。

子问题:假设s[i][j]表示从i到j的子串,则判断s[i][j]是否是回文串之前需要检查s[i+1][j-1]是否是回文串

第二步:转移方程

第三步:初始条件与边界值

初始条件:单个字符串的值一定会是回文串,所以对角线上f[i][i]=true

等价于j-i+1<4,等价于收尾去掉没有字符或者收尾去掉只有一个字符的时候,不需要继续检查子串是否是回文,直接设置f[i][j]=true

第四步:运算顺序

计算f[i][j]时,要参考f[i+1][j-1]的值,而f[i+1][j-1]在f[i][j]的左下方,所以不能够行优先遍历,只能列优先。这样才能保证在计算f[i][j]时,左下角的都已经计算过了。

  • 收尾字符不相等
    • 不是回文串
  • 收尾字符相等
    • 去掉收尾字符只剩下一个字符或者0个字符,直接可以判断是回文传
    • 长度足够,进一步判断子串是否是回文传
  string longestPalindrome(string s) {
        int n=s.length();
        if(n<2)return s;

        vector<vector<bool>> f(n, vector<bool>(n,false));
        int begin=0;
        int maxlen=1;//回文串的长度至少是1
        for(int i=0;i<n;i++)f[i][i]=true;//对角线初始化为true
       
        for(int j=1;j<n;j++){//列优先,所以从j开始遍历,f[0][0]和f[n-1][n-1]已经被初始化了
            for(int i=0;i<j;i++){
                if(s[i]!=s[j])f[i][j]=false;//如果收尾字符不相等,直接判断不是回文串
                else {//如果收尾字符相等
                    if(j-i<3)f[i][j]=true;//去掉收尾字符只剩下1个字符或者0个字符,直接判断是回文串
                    else f[i][j]=f[i+1][j-1];
                }

                if(f[i][j]&&j-i+1>maxlen)
                {
                    maxlen=j-i+1;
                    begin=i;
                }
            }
        }
        return s.substr(begin,maxlen);

    }

【方法二:中心扩散法】

  • 往左寻找与当期位置相同的字符,直到遇到不相等为止。
  • 往右寻找与当期位置相同的字符,直到遇到不相等为止。
  • 最后左右双向扩散,直到左和右不相等。
  • 注意:s.substr(起点,长度)
 string longestPalindrome(string s) {
        if(s.length()<2)return s;
        int left=0,right=0;
        int len=1,maxlen=0,maxStart = 0;

        for(int i=0;i<s.length();i++)
        {
            left=i-1;
            right=i+1;
            while(left>=0&&s[left]==s[i]){
                left--;
                len++;
            }
            while(right<s.length()&&s[right]==s[i]){
                right++;
                len++;
            }
            while(left>=0&&right<s.length()&&s[left]==s[right]){
                left--;
                right++;
                len+=2;
            }
            if(len>maxlen){
                maxlen=len;
                maxStart=left;
            }
            len=1;
        }
        return s.substr(maxStart+1,maxlen);
    }

猜你喜欢

转载自blog.csdn.net/qq_39328436/article/details/112685841