博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
LeetCode Add to List 5. Longest Palindromic Substring
阅读量:7022 次
发布时间:2019-06-28

本文共 4073 字,大约阅读时间需要 13 分钟。

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"

转自:http://www.cnblogs.com/grandyang/p/4464476.html

这道题让我们求最长回文子串,首先说下什么是回文串,就是正读反读都一样的字符串,比如 "bob", "level", "noon" 等等。那么最长回文子串就是在一个字符串中的那个最长的回文子串。LeetCode中关于回文串的题共有五道,除了这道,其他的四道为 Palindrome Number 验证回文数字, Validate Palindrome 验证回文字符串,Palindrome Partitioning 拆分回文串,Palindrome Partitioning II 拆分回文串之二,我们知道传统的验证回文串的方法就是两个两个的对称验证是否相等,那么对于找回文字串的问题,就要以每一个字符为中心,像两边扩散来寻找回文串,这个算法的时间复杂度是O(n*n),可以通过OJ,就是要注意奇偶情况,由于回文串的长度可奇可偶,比如"bob"是奇数形式的回文,"noon"就是偶数形式的回文,两种形式的回文都要搜索,参见代码如下:

 

1 class Solution { 2 public: 3     string longestPalindrome(string s) { 4         int left = 0; 5         int right = 0; 6         int cur_len = 0; 7         int len = 0; 8         int start = 0; 9         10         for(int i = 0; i < s.size() - 1; ++ i)11         {12             if(s[i] == s[i + 1])13             {14                 left = i;15                 right = i + 1;16                 searchPalidrome(s, left, right, cur_len);17             }18             19             if(len < cur_len)20             {21                 start = left;22                 len = cur_len;23             }24             25             left = right = i;26             searchPalidrome(s, left, right, cur_len);27             28             if(len < cur_len)29             {30                 start = left;31                 len = cur_len;32             }33         }34         if(len == 0)35             len = s.size();36         37         return s.substr(start, len);38     }39     40 private:41     void searchPalidrome(string s, int &left, int &right, int &cur_len)42     {43         while(right < s.size() && left >= 0)44         {45             if(s[left] == s[right])46             {47                 cur_len = right - left + 1;48                 -- left;49                 ++ right;50             }51             else break;52         }53         ++ left;54     }55 };

  

此题还可以用动态规划Dynamic Programming来解,根的解法很类似,我们维护一个二维数组dp,其中dp[i][j]表示字符串区间[i, j]是否为回文串,当i = j时,只有一个字符,肯定是回文串,如果i = j + 1,说明是相邻字符,此时需要判断s[i]是否等于s[j],如果i和j不相邻,即i - j >= 2时,除了判断s[i]和s[j]相等之外,dp[j + 1][i - 1]若为真,就是回文串,通过以上分析,可以写出递推式如下:

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 dp[s.size()][s.size()] = {
0}; 5 int left = 0; 6 int right = 0; 7 int len = 0; 8 for(int j = 0; j < s.size(); ++ j) 9 {10 dp[j][j] = 1;11 for(int i = 0; i < j; ++ i)12 {13 dp[i][j] = (s[i] == s[j]) && (j - i == 1 || dp[i + 1][j - 1]);14 if(dp[i][j] && len < j - i + 1)15 {16 len = j - i + 1;17 left = i;18 right = j;19 }20 }21 }22 23 return s.substr(left, right - left + 1);24 }25 };

最后要来的就是大名鼎鼎的马拉车算法Manacher's Algorithm,这个算法的神奇之处在于将时间复杂度提升到了O(n)这种逆天的地步,而算法本身也设计的很巧妙,很值得我们掌握,参见我另一篇专门介绍马拉车算法的博客,代码实现如下:

 

解法三:

class Solution {public:    string longestPalindrome(string s) {        string t ="$#";        for (int i = 0; i < s.size(); ++i) {            t += s[i];            t += '#';        }        int p[t.size()] = {0}, id = 0, mx = 0, resId = 0, resMx = 0;        for (int i = 0; i < t.size(); ++i) {            p[i] = mx > i ? min(p[2 * id - i], mx - i) : 1;            while (t[i + p[i]] == t[i - p[i]]) ++p[i];            if (mx < i + p[i]) {                mx = i + p[i];                id = i;            }            if (resMx < p[i]) {                resMx = p[i];                resId = i;            }        }        return s.substr((resId - resMx) / 2, resMx - 1);    }};
 

转载于:https://www.cnblogs.com/xjtuchenpeng/p/7726642.html

你可能感兴趣的文章
挖一口自己的井
查看>>
[Dart] Flutter 上传文件
查看>>
XML概述
查看>>
leetcode-598-Range Addition II
查看>>
springboot + shiro 验证码与记住登录
查看>>
小猿圈分享HTML5中form如何关闭自动完成功能的方法
查看>>
Carthage 安装与使用
查看>>
详解 Cookie,Session,Token
查看>>
jq 登录正则验证
查看>>
TCP之三次握手和四次挥手
查看>>
【算法学习笔记】70.回文序列 动态规划 SJTU OJ 1066 小M家的牛们
查看>>
phpcms v9 评论的bug.
查看>>
使用Jmeter进行APP接口测试经验总结
查看>>
微信智能硬件应用——微信插座控制
查看>>
有关public接口和友元类的讨论
查看>>
Poj 1050 分类: Translation Mode ...
查看>>
bk.
查看>>
ASP.NET页面间跳转和传递数据(转)
查看>>
使用Coding体验小记
查看>>
bind封装
查看>>