Leetcode--Longest Palindromic Substring(0005)
Posted igoslly
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Leetcode--Longest Palindromic Substring(0005)相关的知识,希望对你有一定的参考价值。
【转载请注明】http://www.cnblogs.com/igoslly/p/8726771.html
来看一下题目:
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"
|
题目意思: 给出字符串中最长的回文串 若长度相同,给出位置最前的 |
作为较经典的题目,回文串通常有几种方法,已经有很多人分析过了,提供链接:https://segmentfault.com/a/1190000005063336
总的来说:
1、穷举法
对于长度为 n 的字符串,有字符串 n(n+1)/2 ,判断是否回文串复杂度为 O(n),算法整体复杂度为 O(n^3)
2、中心扩展法
对于回文串,从对称轴展开的字符均相同;把字符串的每个位置作为回文串的对称轴,判断回文串的最大长度;子串对称轴遍历复杂度为O(n),回文判断O(n)
这里要注意:长度为奇数 / 偶数时,对称轴的位置不同
class Solution { public: int max=0; string res=""; string longestPalindrome(string s) { if(s.size()==1){return s;} int len=s.size(); for(int i=0;i<len-1;i++){ // 字符串从0 ~ len-2位置,i&i进行奇数判断,i&i+1进行偶数判断 check(s,i,i); check(s,i,i+1); } return res; } // 判断回文串最大长度 void check(string s,int i,int j){ while(i>=0&&j<s.size()){ // 若两边扩展字符相等,更新最大长度 if(s[i]==s[j]){ if(j-i+1>max){ max=j-i+1; res=s.substr(i,max); } i--; j++; }else{ return; } } } };
给出一个Leetcode大神的代码,也是以中心扩展法为基本思想
class Solution { public: string longestPalindrome(string s) { // 去除长度为0、1情况 if (s.empty()) return ""; if (s.size() == 1) return s; // 记录最长回文串的起始位置、最大长度 int min_start = 0, max_len = 1; for (int i = 0; i < s.size();) { if (s.size() - i <= max_len / 2) break; int j = i, k = i; // 以i作为中心位置,进行两边扩展 // 若中心毗邻字符串,则直接包含在内;因为中心位置相同字母必然对称 while (k < s.size()-1 && s[k+1] == s[k]) ++k; // Skip duplicate characters. i = k+1; // 以j,k向两边扩展,进行比较更新 while (k < s.size()-1 && j > 0 && s[k + 1] == s[j - 1]) { ++k; --j; } // Expand. int new_len = k - j + 1; if (new_len > max_len) { min_start = j; max_len = new_len; } } return s.substr(min_start, max_len); } };
3、Manacher算法
俗称“马拉车算法”,是在中心扩展法的基础上,优化确定最大长度的算法;
专门设定长度数组(假设为p[len]),记录每个位置的最大长度;
为了避免长度奇偶问题,在原字符串的中间,插入‘#’异常符号;
举个例子:
s="abbahopxpo"
转换为
s_new="$#a#b#b#a#h#o#p#x#p#o#"
有较为形象具体的说明:https://segmentfault.com/a/1190000008484167
实现代码:
string add_string(string s){ string news="$#"; int len=s.size(); int j=2; for(int i=0;i<len;i++){ news+=s[i]; news+=\'#\'; } return news; } class Solution { public: string longestPalindrome(string s) { s=add_string(s); int len=s.size(),maxlen=-1; int id,mx=0,p[len],maxindex; for(int i=1;i<len;i++){ if(i<mx) {p[i]=min(p[2*id-i],mx-i); }else{p[i]=1;} while(s[i-p[i]]==s[i+p[i]]) p[i]++; if(mx<i+p[i]){ id=i; mx=i+p[i]; } if(maxlen<p[i]-1){ maxlen=p[i]-1; maxindex=i; } } string result=""; for(int i=maxindex-maxlen;i<=maxindex+maxlen;i++){ if(s[i]!=\'#\'&&s[i]!=\'$\'){ result+=s[i]; } } return result; } };
以上是关于Leetcode--Longest Palindromic Substring(0005)的主要内容,如果未能解决你的问题,请参考以下文章
[Leetcode]Longest Palindromic Substring
leetcode longest consecutive sequence
LeetCode Longest Increasing Subsequence