首页 > 代码库 > 5. Longest Palindromic Substring

5. Longest Palindromic Substring

5. Longest Palindromic Substring

  • Total Accepted: 170563
  • Total Submissions: 688595
  • Difficulty: Medium
  • Contributors: Admin

Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.

Example:

Input: "babad"

Output: "bab"

Note: "aba" is also a valid answer.

Example:

Input: "cbbd"

Output: "bb"

Solution 1:

两两对称验证。以每一个字符为中心,左右扩散来找回文串。注意奇数个aba和偶数个abba两种。时间复杂度是O(n2)

 1 class Solution {
 2 public:
 3     string longestPalindrome(string s) {
 4         int startIdx = 0;
 5         int left = 0, right = 0;
 6         int len = 0;
 7         for(int i = 0; i < s.size() - 1; i++){
 8             if(s[i] == s[i + 1]){//偶数个palin
 9                 left = i;
10                 right = i + 1;
11                 searchPalin(s, left, right, startIdx, len);
12             }
13             left = right = i;//奇数个palin
14             searchPalin(s, left, right, startIdx, len);
15         }
16         if(len == 0) len = s.size();//in case like "a", 如果len是0, 则会return一个空串
17         return s.substr(startIdx, len);
18     }
19     
20     void searchPalin(string s, int& left, int& right, int& startIdx, int& len){
21         int step = 1;//左右延展判断的时候走的步数
22         while(left - step >= 0 && right + step < s.size()){
23             if(s[left - step] != s[right + step]) break;//步数palin要break
24             ++step;//这里的step要比真正走的步数要大一,所以对于以后的计算len和startIdx的时候要小心
25         }
26         //if(len == 0) len = s.size();
27         int wide = right - left + step * 2 - 1;
28         //startIdx = left - step + 1;
29         if(len < wide){
30             len = wide;
31             startIdx = left - step + 1;
32         }
33     }
34 };

Solution 2: 动态规划DP

dp[i][j]:代表i到j之间是否为回文串。

dp[i, j] = 1                                               if i == j

           = s[i] == s[j]                                if j = i + 1

           = s[i] == s[j] && dp[i + 1][j - 1]    if j > i + 1      

这里有个有趣的现象就是如果我把下面的代码中的二维数组由int改为vector<vector<int> >后,就会超时,这说明int型的二维数组访问执行速度完爆std的vector啊,所以以后尽可能的还是用最原始的数据类型吧。

 1 class Solution {
 2 public:
 3     string longestPalindrome(string s) {
 4        int n = s.size();
 5        bool dp[n][n] = {false};
 6        int len = 0;
 7        int left = 0, right = 0;
 8        /*
 9        for(int i = 0; i < n; i++){//初始化:单个字符是回文串
10            dp[i][i] = true;
11        }
12        for(int i = 0; i < n - 1; i++){
13            dp[i][i + 1] = s[i] == s[i + 1];//初始化:j = i + 1的情况下
14        }*/
15        //for(int j = 2; j < n; j++){//j > i + 1
16            //for(int i = 0; i < j - 1; i++){
17        for(int j = 0; j < n; j++){//综合起来
18            for(int i = 0; i < j; i++){//i < j 所以dp[j][j]要写在最外层循环下面
19                //dp[i][j] = (s[i] == s[j]) && dp[i + 1][j - 1];
20                dp[i][j] = (s[i] == s[j]) && (dp[i + 1][j - 1] || j - i <= 1);
21                if(dp[i][j] && j - i + 1 > len){
22                    len = j - i + 1;
23                    left = i;
24                    right = j;
25                }
26                //dp[j][j] = true;
27            }
28            dp[j][j] = true;
29        }
30        return s.substr(left, right - left + 1);//最后不是返回dp的值,而是substring
31     }
32 };

Solution 3: Manacher‘s Algorithms 马拉车算法 时间复杂度O(n)

 

5. Longest Palindromic Substring