力扣 5. 最长回文子串

题目

最长回文子串

题目

解题过程

始终如一的暴力

  1. 看到题目我就想到之前做的回文子串的题目。我可以从字符串的左边开始将所有的字符子串排列出来,然后用一个函数判断该子串是否为回文串。如果是,就和当前已有回文子串的长度进行比较,如果比当前已有的子串长,就记录下该字符串的长度和起始下标。当所有的情况都验证完以后,利用长度和起始下标,从字符串中截出子串,并返回。
class Solution {
public:
     //判断字符串是否为回文串
     bool adjust(string s, int i, int j){
         while(j >= i){
             if(s[i] != s[j]){
                 return false;
             }
            j--;
            i++;
         }
		 return true;
    }

    string longestPalindrome(string s) {
        int len = s.size();//记录字符串长度
        if(len < 2) return s;
        //分别记录能找到的最长回文子串的第一个字符和最后一个字符在s中的位置
        int left = 0, right = 0;
        //通过i,j来将字符串所有可能的子串全部枚举出来,然后进行判断
        for(int i = 0; i < len - 1; i++){
            for(int j = i + 1; j < len; j++){
                if(adjust(s,i,j) && (j - i + 1 > right - left + 1)){
                    left = i;
                    right = j;
                }
            }
        }

        string str = s.substr(left,right-left+1);//用来记录回文子串
        return str;
    }
};

时间复杂度是O(n^3),空间复杂度是O(1) 。提交超时了。但是我看见题解里面有一个用Java暴力破解的好像能通过。

令人头疼的动态规划

  1. 不用说了,这肯定是在题解里面看到的方法。
  2. 其实这个方法也需要将所有的子串走一遍。但是他借助了前面的比较结果。因为,一个字符串要是回文串的话,除开两端的字符以外剩下的子串也肯定是回文串。所以,判断这条字符串是否为回文串,只需要判断两端的字符是否相等并且中间的子串是否为回文串。状态转移方程就为:
    状态转移方程
  3. 这样就借助了前面判断的情况,不用每一条子串都从头到尾再去判断是否为回文串。节省了一个判断的时间,时间复杂度就少了个n。
class Solution {
public:
    string longestPalindrome(string s) {
        int len = s.size();
        if(len < 2) return s;

        vector<vector<int>> dp(len,vector<int>(len));
        int maxlen = 0;
        int begin = 0;
        //外层循环是用来规定当前子串的长度的
        for(int length = 0; length < len; length++){
        	//内层循环是用来规定当前子串的起始下标
            for(int i = 0; i < len - length; i++){
                int j = i + length;//j就是子串的终止下标
                //当length为0时,只有一个字符,肯定是回文串
                if(length == 0){
                    dp[i][j] = 1;
                }
                //当length为1时,有两个字符串,判断这两个字符是否相等即可
                else if(length == 1){
                    dp[i][j] = (s[i] == s[j]);
                }
                //当length超过1之后,就需要用状态转移方程来判断
                else{
                    dp[i][j] = dp[i+1][j-1] && (s[i] == s[j]);
                }
                if(dp[i][j] && maxlen < j - i + 1){
                    maxlen = j - i + 1;
                    begin = i;
                }
            }
        }
        string ans = s.substr(begin, maxlen);
        return ans;
    }
};

时间复杂度是O(n ^ 2) ,空间复杂度是O(n^2),用空间换时间。

展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 数字20 设计师: CSDN官方博客
应支付0元
点击重新获取
扫码支付

支付成功即可阅读