005 Longest Palindromic Substring [Leetcode]
来源:互联网 发布:耀夜姬t恤淘宝 编辑:程序博客网 时间:2024/05/16 07:30
题目内容:
Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring.
解题思路:
比较直观的方法,就是以每个字符串为中心点,向前后同时遍历直到两边字符不同,并记录下字符长度。但这样无法处理字符串为偶数的情况。因此,我们可以先对字符串做一个处理,在每两个字符之间插入一个不会出现的字符,如‘#’,然后执行上述算法。
代码如下,这样的算法复杂度为
class Solution {public: string longestPalindrome(string s) { int size = s.size(); if(size == 0 || size == 1) return s; size = size*2 + 1; string str(size, '#'); for(int i = 1; i != size; i+=2) str[i] = s[i>>1]; int maxR(0), max_index(0); int *len = new int[size]; len[0] = 1; int begin(0), end(0), temp(0); for(int i = 1; i != size; ++i) { temp = len[i-1]/2 + i-1; maxR = maxR > temp ? maxR : temp; begin = i; end = i; len[i] = 1; while(begin != 0 && end != size - 1 && str[--begin] == str[++end]) len[i] += 2; if(len[i] > len[max_index]) max_index = i; } string result = s.substr((max_index - len[max_index]/2)/2, len[max_index]/2); delete[] len; len = 0; return result; }};
在hiho中有对此题详细的解释。主要推导过程如下:
小Ho这一想就是三天,小Hi也是看不下去了,决定来开导开导小Ho:“小Ho,你有没有想过,在之前的计算中,计算出以每一个位置为中心的最长回文子串的长度有没有什么用呢?”
小Ho答道:“我想想,如果以第5个字符为中心的最长回文子串的长度是5的话,这就告诉了我[3, 7]这一段是一个回文子串,所以呢?”
小Hi继续提示道:“假设这时候你想要计算以第6个字符为中心的最长回文子串的长度,你有没有什么已知的信息了?”
小Ho边想边说道:“唔,首先第6个字符和第4个字符是一样的,第7个字符和第3个字符是一样的,而第5个字符本身就肯定和第5个字符一样,那么如果[3, 5]这一段是回文子串的话,那么[5, 7]这一段肯定也是回文子串。也就是说,如果令f[i] 表示以第i个字符为中心的最长回文子串的长度,我们就会有f[i] >= f[i–2]?”
“不对,还要考虑到f[i – 1]的值,如果f[i – 1]太小就没有意义了,应该是f(i)≥min{f(i-2), f(i-1)-2}。”小Ho接着补充道。
“没错,但是还有一个问题,如果此时我告诉你f(5) = 1,但是f(4) = 7, f(2) = 3呢?”小Hi追问道。
小Ho想了想,回答道:“理论上来说,我可以通过这些信息知道f(6)>=3,但是由于f(5)=1所以我只能计算出来f(6)>=-1我知道了,我不应该是通过f(i – 1)来辅助计算,而是通过使得右边界(j + f(j) / 2)最大的那个j来辅助计算才是,所以公式将变成 f(i) ≥ min{f(2*j-i) , f(j) -2*(i-j)}这种形式了!”
小Hi继续问道:“那知道了这个公式之后,你打算怎么做呢?”
小Ho想也没想便道:“这简单,我只要在之前枚举中心位置那种方法的基础上,统计使得回文串右边界(j + f(j) / 2)最大的那个j,然后再计算每一个i的时候,都可以通过f(i)≥min{f(2*j-i), f(j)-2*(i-j)}这个公式来知道f(i)的一个最小值,这样即使是在我们所提到的那种最坏情况下,也可以节省掉很多不必要的计算呢~
代码实现如下:
class Solution {public: string longestPalindrome(string s) { int size = s.size(); if(size == 0 || size == 1) return s; size = size*2 + 1; string str(size, '#'); for(int i = 1; i != size; i+=2) str[i] = s[i>>1]; int maxR(0), max_index(0); int *len = new int[size]; len[0] = 1; int begin(0), end(0), temp(0); for(int i = 1; i != size; ++i) { temp = len[i-1]/2 + i-1; maxR = len[maxR]/2+maxR > temp ? maxR : i-1; begin = i; end = i; len[i] = 1; int temp1 = (maxR == 0 ? 1 : len[2*maxR - i]); int temp2 = len[maxR] - 2*(i-maxR); temp = (temp1 > temp2 ? temp2 : temp1); if(temp > 1) { begin = i - temp/2; end = i + temp/2; len[i] = temp; } while(begin != 0 && end != size - 1 && str[--begin] == str[++end]) len[i] += 2; if(len[i] > len[max_index]) max_index = i; } string result = s.substr((max_index - len[max_index]/2)/2, len[max_index]/2); delete[] len; len = 0; return result; }};
还有的方法,推测可以使用后缀树来实现。
- leetcode-005:Longest Palindromic Substring
- LeetCode-005 Longest Palindromic Substring
- LeetCode 005 Longest Palindromic Substring
- [LeetCode]-005-Longest Palindromic Substring
- LeetCode 005 Longest Palindromic Substring
- 005 Longest Palindromic Substring [Leetcode]
- [LeetCode]005-Longest Palindromic Substring
- LeetCode 005 Longest Palindromic Substring
- leetcode Longest Palindromic Substring 005
- LeetCode 005 Longest Palindromic Substring *
- LeetCode 005: Longest Palindromic Substring
- leetcode-005 Longest Palindromic Substring
- leetcode 005 Longest Palindromic Substring
- LeetCode-005 Longest Palindromic Substring
- LeetCode: Longest Palindromic Substring
- LeetCode Longest Palindromic Substring
- LeetCode: Longest Palindromic Substring
- [Leetcode] Longest Palindromic Substring
- linux shell 的here document 用法 (cat << EOF)
- 【鸟哥的linux私房菜-学习笔记】认识与分析登录文件
- 解决chrome下https无法打开方法
- jquery datatable 参数
- HTTP协议是无状态协议,怎么理解?
- 005 Longest Palindromic Substring [Leetcode]
- 树与二叉树
- 旅行商问题 打印路径
- Android 6.0新特性
- poj 2888 Magic Bracelet polya计数+矩阵统计路径数
- jpush(极光)推送之 IOS 篇
- 【自动化测试】RIDE的使用
- linux 搭建memcached服务
- 深入理解Java:注解(Annotation)自定义注解入门