5最长回文子串

给你一个字符串 s,找到 s 中最长的回文子串。

如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。

 

题解:首先尝试了最暴力解法,发现时间超时,后来根据回文串的特点,回文串去掉首字符和尾字符的子字符串必然是回文串,然后去反推,先用了中心扩展法尝试,然后又用了dp的解法去尝试解出。

复制代码
#include "../include/leetcode.h"

// class Solution {
// public:
//     string longestPalindrome(string s) {
//         // 最暴力的方法
//         int longestDistance = 1;
//         int longestBegin = 0;
//         for (int i = 0; i < s.size(); ++i) {
//             for (int j = longestDistance; (i + j) <= s.size(); ++j) {
//                 string str1, str2;
//                 str1 = str2 = s.substr(i, j);
//                 reverse(str2.begin(), str2.end());
//                 if(str1 == str2 && j > longestDistance)      {
//                     longestDistance = j;
//                     longestBegin = i;
//                 }
//             }
//         }
//         return s.substr(longestBegin, longestDistance);
//     }
// };


//官方答案 动态规划
class Solution {
public:
    int maxLen;
    int maxLenBegin;

    string longestPalindrome(string s) {
        int n = s.size(); 
        vector<vector<bool> > dp(n, vector<bool>(n, false));

        maxLen = 1;
        maxLenBegin = 0;

        for (int i = 0; i < n - 1; ++i) {
            dp[i][i] = true;
            if (s[i] == s[i + 1]) {
                dp[i][i + 1] = true;
                maxLen = 2;
                maxLenBegin = i;
            }
        }

        dp[n - 1][n - 1] = true;

       
        //长度
        for (int l = 3; l <= n; ++l) {
            //起始位置
            for (int i = 0; i + l <= n; ++i) {
                int j = i + l - 1;

                if (s[i] == s[j]) {
                    dp[i][j] = dp[i + 1][j - 1]; 
                    if (l > maxLen && dp[i][j]) {
                        maxLen = l;
                        maxLenBegin = i;
                    }
                    
                } 
            }
        }

        // printDp(dp);

        return s.substr(maxLenBegin, maxLen);
    }
};

//官方解法 中心扩展算法
// class Solution {
// private:
//     int maxLenBegin;
//     int maxLen;
// public:
//     void expandAroundCenter(string & s, int l, int r) {
//         if (l - 1 >= 0 && r + 1 < s.size() && s[l - 1] == s[r +1]) {
//             if ( maxLen < r - l + 3) {
//                 maxLen = r - l + 3;
//                 maxLenBegin = l - 1;
//             } 
            
//             expandAroundCenter(s, l - 1, r + 1);
//         }
//     }


//     string longestPalindrome(string s) {
//         maxLen = 1;
//         maxLenBegin = 0;
//         for (int i = 0; i < s.size() - 1; ++i) {
//             expandAroundCenter(s, i, i);
//             if (s[i] == s[i + 1]) {
//                 if (maxLen < 2) {
//                     maxLen = 2;
//                     maxLenBegin = i;
//                 }
//                 expandAroundCenter(s, i, i + 1);
//             }
//         }
//         // expandAroundCenter(s, 2, 2);

//         return s.substr(maxLenBegin, maxLen);
        
//     }
// };


int main() {
     string s = "ccc";
     cout << s << endl;
     Solution ms;
     cout << ms.longestPalindrome(s) << endl;
}
复制代码

 

posted @   woodx  阅读(21)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示