Loading

LeetCode 5. 最长回文子串

思路

方法一:暴力法,双重循环判断

 1 class Solution {
 2 public:
 3     //暴力法,时间复杂度O(n^2),提交之后会超时,不能accept
 4     string longestPalindrome(string s) {
 5         int slen = s.length();
 6         string maxPalindrome(1, s[0]);
 7         for(int i = 0; i <= slen-2; ++i) {
 8             for(int j = i+1; j <= slen-1; ++j) {
 9                 if(s[i] == s[j] && isPalindrome(s, i, j)) {
10                     if(j-i+1 > maxPalindrome.length())
11                         maxPalindrome = s.substr(i, j-i+1);
12                 }
13             }
14         }
15 
16         return maxPalindrome;
17     }
18 
19     //判断回文串
20     bool isPalindrome(const string& s, int i, int j) {
21         while(i < j) {
22             if(s[i] != s[j]) {
23                 return false;
24             }
25 
26             ++i;
27             --j;
28         }
29 
30         return true;
31     }
32 };

复杂度分析:

时间复杂度:O(n3),双重循环嵌套一个判断回文串的函数,双重循环是O(n2),判断回文串是O(n)。

 

方法二:动态规划

 1 class Solution {
 2 public:
 3     string longestPalindrome(string s) {
 4         int slen = s.length();
 5         string maxPalindrome(1, s[0]);  //初始化为第一个字符
 6         vector<vector<bool>> dp(slen, vector<bool>(slen, false));
 7 
 8         for(int len = 0; len < slen; ++len) {
 9             for(int i = 0; i + len < slen; ++i) {
10                 int j = i+len;
11                 if(j-i == 0) {
12                     dp[i][j] = true;
13                 } else if(j-i == 1) {
14                     dp[i][j] = (s[i] == s[j]);
15                 } else {
16                     dp[i][j] = (s[i] == s[j] && dp[i+1][j-1]);
17                 }
18 
19                 if(dp[i][j] && j-i+1 > maxPalindrome.length()) {
20                     maxPalindrome = s.substr(i, j-i+1);
21                 }
22             }
23         }
24         
25 
26         return maxPalindrome;
27     }
28 };

 

 

方法三:中心扩展算法

 1 class Solution {
 2 public:
 3     string longestPalindrome(string s) {
 4         int start = 0, end = 0;
 5         for (int i = 0; i < s.length(); i++) {
 6             int len1 = expandAroundCenter(s, i, i);
 7             int len2 = expandAroundCenter(s, i, i + 1);
 8             int len = max(len1, len2);
 9             if (len > end - start) {
10                 start = i - (len - 1) / 2;
11                 end = i + len / 2;
12             }
13         }
14         return s.substr(start, end - start + 1);
15     }
16 
17     int expandAroundCenter(const string& s, int left, int right) {
18         while (left >= 0 && right < s.length() && s[left] == s[right]) {
19             --left;
20             ++right;
21         }
22         return right - left - 1;
23     }
24 };

 

 

 

方法四:Manacher 算法 (马拉车算法)

还有一个复杂度为 O(n)Manacher 算法。然而本算法十分复杂,一般不作为面试内容。这里给出,仅供有兴趣的同学挑战自己。

具体见:LeetCode官方题解 - 最长回文子串

 

 

参考

本文转载自:LeetCode官方题解 - 最长回文子串

 

posted @ 2021-02-25 15:17  拾月凄辰  阅读(88)  评论(0编辑  收藏  举报