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

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

description:

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

Example:

Example 1:Input: "babad"Output: "bab"Note: "aba" is also a valid answer.Example 2:Input: "cbbd"Output: "bb"

my answer:

解法一:比较简单的想法就是一个字符串从头开始遍历,对于每个字符都分别向两边走,左边和右边一样就走一步,一直到不一样了,那就是对于中间这个字符就已经是最大回文长度了,和之前的最大比一下,之后进行下一个字符,所以时间复杂度是n^2。然后还有两个特殊的case,第一个是字串本身小于3的话,那一定是回文的,还有就是遍历的时候,假设说当前最大长度是7,现在遍历到倒数第三个字符了,也就是说就算是它右边的俩和它左边俩一样的就是回文它最长也就是5了,所以当剩余n-i < maxlength/2的时候就停了。

下面两个答案,上边是我的,底下是大佬的,md就是一样的嘛,无fuck可说,我的就是一直一直runtimeerror【微笑】。

// class Solution {// public://     string longestPalindrome(string s) {//         if (s.size() < 2) return s;//         int n = s.size(), maxlength = 0, start = 0;//         for (int i = 0; i < n; ){//             if(n - i <= maxlength / 2) break;//             int left =i, right = i;//             while(s[right] == s[right + 1] && right < n - 1) ++right;//             i = right + 1;//             while(s[left - 1] == s[right + 1] && right < n - 1 && left > 0){//                 --left;//                 ++right;//             }//             // maxlength = max(maxlength, right - left + 1); //             // start = left;//             if (maxlength < right - left + 1) {//                 maxlength = right - left + 1;//                 start = left;//             }//         }//         return s.substr(start, maxlength);//     }// };class Solution {public:    string longestPalindrome(string s) {        if (s.size() < 2) return s;        int n = s.size(), maxLen = 0, start = 0;        for (int i = 0; i < n;) {            if (n - i <= maxLen / 2) break;            int left = i, right = i;            while (right < n - 1 && s[right + 1] == s[right]) ++right;            i = right + 1;            while (right < n - 1 && left > 0 && s[right + 1] == s[left - 1]) {                ++right; --left;            }            if (maxLen < right - left + 1) {                maxLen = right - left + 1;                start = left;            }        }        return s.substr(start, maxLen);    }};

方法二:

卧槽真的太难了,这个算法叫做manacher算法,哪位大佬翻译成马拉车了...
算法还可以,就是在为什么是线性这个问题上想了好久好久,所以为什么呢?之前的就上面那个方法一暴力对每个元素处理,且每个元素都相当于是对所有存在的元素来一次比较所以是n^2,而manacher算法之所以是线性的,是因为他利用里之前的结果,就是之前的元素已经遍历过的他就不会再遍历了,你走一轮就会发现他走的检查的元素都是他右边那些到现在为止程序从来未涉及过的无污染元素,所以因为不重复才会是线性,也是大佬们说马拉车算法的精华就在这一句

p[i] = mx > i ? min(p[2 * id - i], mx - i) : 1;

下面扔上全代码:

#include 
#include
#include
using namespace std;string Manacher(string s) { // Insert '#' string t = "$#"; for (int i = 0; i < s.size(); ++i) { t += s[i]; t += "#"; } // Process t vector
p(t.size(), 0); int mx = 0, id = 0, resLen = 0, resCenter = 0; for (int i = 1; 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 (resLen < p[i]) { resLen = p[i]; resCenter = i; } } return s.substr((resCenter - resLen) / 2, resLen - 1);}int main() { string s1 = "12212"; cout << Manacher(s1) << endl; string s2 = "122122"; cout << Manacher(s2) << endl; string s = "waabwswfd"; cout << Manacher(s) << endl;}

其实主要大体思路还是针对每一个元素去看它两边一样不一样,只不过是不是从它跟前紧第一个开始了,是从确认回文半径+1处开始检查。

relative point get√:

hint :

用ababc试一下,立马就懂了嗯

转载于:https://www.cnblogs.com/forPrometheus-jun/p/10544915.html

你可能感兴趣的文章
UVa 10112 - Myacm Triangles
查看>>
给同一个按钮添加单双击事件
查看>>
form
查看>>
powershell输出错误信息到文件
查看>>
VS不显示最近打开的项目
查看>>
wcf客户端捕获异常
查看>>
MyEclipse安装Freemarker插件
查看>>
计算多项式的值
查看>>
DP(动态规划)
查看>>
chkconfig
查看>>
day44前端开发1之html基础
查看>>
小甲鱼-004改进小游戏
查看>>
琐碎的思绪
查看>>
shell 3数组
查看>>
29个简单直观的移动设备网页设计
查看>>
webform(七)分页
查看>>
中国互联网的十一种盈利模式
查看>>
php中$_REQUEST、$_POST、$_GET的区别和联系小结
查看>>
看了极光推送技术原理的几点思考
查看>>
【转】Vue.js 2.0 快速上手精华梳理
查看>>