LeetCode之“字符串”:最长回文子串
2015-05-23 14:50
417 查看
题目要求:
给出一个字符串(假设长度最长为1000),求出它的最长回文子串,你可以假定只有一个满足条件的最长回文串。例如,给出字符串 "abcdzdcab",它的最长回文子串为 "cdzdc"。
解答:
这个题目的一个简单的解法就是对字符串中的每一个字符,同时向其两边延展,以找到最长回文子串。这种方法是可以的,但要处理回文子串长度为奇数和偶数的两种情况是比较麻烦的。如下图的几个字符串:
“a”
"aa"
"aaa"
"aaaa"
一个比较好的解决方法就是利用Manacher算法。这个算法的核心思想在于为原字符串的开头结尾以及每两个相邻的字符之间加入一个特殊的字符,例如‘#’,以达到统一处理回文子串长度为奇数和偶数的两种情况的目的。如一个字符串为S = “abaaba”,处理之后就是S' = “#a#b#a#a#b#a#”。这样,不管回文子串的长度是奇数还是偶数,我们都可以统一处理,因为通过添加特殊字符,原偶数长度的子串中间多了一个特殊字符,这样就能够将其他和奇数长度的字符串一样处理了。我们只需在最后将特殊字符去掉即可。详细可参考LeetCode上的一篇文章。
在LeetCode上通过的C++代码如下:
View Code
另外,代码已托管至Github.
给出一个字符串(假设长度最长为1000),求出它的最长回文子串,你可以假定只有一个满足条件的最长回文串。例如,给出字符串 "abcdzdcab",它的最长回文子串为 "cdzdc"。
解答:
这个题目的一个简单的解法就是对字符串中的每一个字符,同时向其两边延展,以找到最长回文子串。这种方法是可以的,但要处理回文子串长度为奇数和偶数的两种情况是比较麻烦的。如下图的几个字符串:
“a”
"aa"
"aaa"
"aaaa"
一个比较好的解决方法就是利用Manacher算法。这个算法的核心思想在于为原字符串的开头结尾以及每两个相邻的字符之间加入一个特殊的字符,例如‘#’,以达到统一处理回文子串长度为奇数和偶数的两种情况的目的。如一个字符串为S = “abaaba”,处理之后就是S' = “#a#b#a#a#b#a#”。这样,不管回文子串的长度是奇数还是偶数,我们都可以统一处理,因为通过添加特殊字符,原偶数长度的子串中间多了一个特殊字符,这样就能够将其他和奇数长度的字符串一样处理了。我们只需在最后将特殊字符去掉即可。详细可参考LeetCode上的一篇文章。
在LeetCode上通过的C++代码如下:
class Solution { public: /** * @param s input string * @return the longest palindromic substring */ string longestPalindrome(string& s) { int sz = s.size(); string newStr; for(int i = 0; i < sz; i++) { newStr += "#" + s.substr(i, 1); } newStr += "#"; int szOfNewStr = newStr.size(); int center = 0; int len = 0; for(int i = 0; i < szOfNewStr; i++) { int step = 1; int k = i; int tmpCenter = i; int tmpHalfLen = 0; int tmpLen = 0; if(newStr[i] == '#') { while(k - step > -1 && k + step < szOfNewStr && newStr[k - step] == newStr[k + step]) { tmpHalfLen++; step += 2; } tmpLen = 2 * tmpHalfLen; } else { step++; while(k - step > -1 && k + step < szOfNewStr && newStr[k - step] == newStr[k + step]) { tmpHalfLen++; step += 2; } tmpLen = 2 * tmpHalfLen + 1; } if(tmpLen > len) { len = tmpLen; center = tmpCenter; } } string retStr; if(newStr[center] == '#') { int i = 1; while(i < len) { retStr.insert(retStr.begin(), newStr[center - i]); retStr.insert(retStr.end(), newStr[center + i]); i += 2; } } else { retStr += newStr[center]; int i = 2; while(i < len) { retStr.insert(retStr.begin(), newStr[center - i]); retStr.insert(retStr.end(), newStr[center + i]); i += 2; } } return retStr; } };
View Code
另外,代码已托管至Github.
相关文章推荐
- Longest Palindromic Substring 在一个字符串里找最长回文子串@LeetCode
- 【LeetCode004-005算法/编程练习C++】--两个数组的中间数,找出最长回文子串
- leetcode 409. Longest Palindrome 可以构造的最长的回文字符串
- Manacher算法: O(n)时间求字符串的最长回文子串
- [leetcode]5. 最长回文子串
- 每天一道LeetCode-----最长回文子串/序列,从头开始的最长回文子串长度
- 找工作知识储备(2)---数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串
- 字符串的最长回文子串问题
- 2014再见 2015你好 【附带】[LeetCode]最长回文子串
- hihoCoder - 1032 - 最长回文子串 (字符串~)
- LeetCode 5. Longest Palindromic Substring(最长回文子串)
- 字符串最长回文子串
- bupt 204 Palindrome 求字符串任意区间的最长回文子串 二分答案+后缀数组
- 求字符串的最长回文子串--最直观的“马拉车算法”分析
- 求最长回文子串 - leetcode 5. Longest Palindromic Substring
- 最长回文子串(Manacher算法模板题)&&对称字符串问题
- [C++]LeetCode: 99 Longest Palindromic Substring (最长回文子串)
- leetcode5-Longest Palindromic Substring(最长回文子串)
- leetcode_最长回文字符串
- 求字符串中的最长回文子串