LeetCode之“字符串”:最长回文子串

  题目要求:

  给出一个字符串(假设长度最长为1000),求出它的最长回文子串,你可以假定只有一个满足条件的最长回文串。例如,给出字符串 "abcdzdcab",它的最长回文子串为 "cdzdc"。

  

  解答:

  这个题目的一个简单的解法就是对字符串中的每一个字符,同时向其两边延展,以找到最长回文子串。这种方法是可以的,但要处理回文子串长度为奇数和偶数的两种情况是比较麻烦的。如下图的几个字符串:

  “a”

  "aa"

  "aaa"

  "aaaa"

  一个比较好的解决方法就是利用Manacher算法。这个算法的核心思想在于为原字符串的开关结尾以及每两个相邻的字符之间加入一个特殊的字符,例如‘#’,以达到统一处理回文子串长度为奇数和偶数的两种情况的目的。如一个字符串为S = “abaaba”,处理之后就是S‘ = “#a#b#a#a#b#a#”。这样,不管回文子串的长度是奇数还是偶数,我们都可以统一处理,因为通过添加特殊字符,原偶数长度的子串中间多了一个特殊字符,这样就能够将其他和奇数长度的字符串一样处理了。我们只需在最后将特殊字符去掉即可。详细可参考LeetCode上的一篇文章

  在LeetCode上通过的C++代码如下:

 1 class Solution {
 2 public:
 3     /**
 4      * @param s input string
 5      * @return the longest palindromic substring
 6      */
 7     string longestPalindrome(string& s) {
 8         int sz = s.size();
 9         string newStr;
10         for(int i = 0; i < sz; i++)
11         {
12             newStr += "#" + s.substr(i, 1);
13         }
14         newStr += "#";
15
16         int szOfNewStr = newStr.size();
17         int center = 0;
18         int len = 0;
19
20         for(int i = 0; i < szOfNewStr; i++)
21         {
22             int step = 1;
23             int k = i;
24             int tmpCenter = i;
25             int tmpHalfLen = 0;
26             int tmpLen = 0;
27
28             if(newStr[i] == ‘#‘)
29             {
30                 while(k - step > -1 && k + step < szOfNewStr && newStr[k - step] == newStr[k + step])
31                 {
32                     tmpHalfLen++;
33                     step += 2;
34                 }
35                 tmpLen = 2 * tmpHalfLen;
36             }
37             else
38             {
39                 step++;
40                 while(k - step > -1 && k + step < szOfNewStr && newStr[k - step] == newStr[k + step])
41                 {
42                     tmpHalfLen++;
43                     step += 2;
44                 }
45                 tmpLen = 2 * tmpHalfLen + 1;
46             }
47
48             if(tmpLen > len)
49             {
50                 len = tmpLen;
51                 center = tmpCenter;
52             }
53
54         }
55
56         string retStr;
57         if(newStr[center] == ‘#‘)
58         {
59             int i = 1;
60             while(i < len)
61             {
62                 retStr.insert(retStr.begin(), newStr[center - i]);
63                 retStr.insert(retStr.end(), newStr[center + i]);
64                 i += 2;
65             }
66         }
67         else
68         {
69             retStr += newStr[center];
70             int i = 2;
71             while(i < len)
72             {
73                 retStr.insert(retStr.begin(), newStr[center - i]);
74                 retStr.insert(retStr.end(), newStr[center + i]);
75                 i += 2;
76             }
77         }
78
79         return retStr;
80
81     }
82 };

  

  另外,代码已托管至Github.

时间: 2024-08-16 16:34:23

LeetCode之“字符串”:最长回文子串的相关文章

【LeetCode】5# 最长回文子串

题目描述 给定一个字符串 s,找到 s 中最长的回文子串.你可以假设 s 的最大长度为 1000. 示例 1: 输入: "babad" 输出: "bab" 注意: "aba" 也是一个有效答案. 示例 2: 输入: "cbbd" 输出: "bb" 思路 本题运用了一些动态规划的思想,关于动态规划,可以看看我之前的一篇博客了解一下. LeetCode 探索初级算法 - 动态规划 1.首先要找到最简情况.这道题

leetcode oj s_05 最长回文子串

1 /** 2 * 最长回文子字符串 3 * 4 * @author 林夕 5 */ 6 public class Solution { 7 8 public static void main(String[] args) { 9 // String s = 10 // "rgczcpratwyqxaszbuwwcadruayhasynuxnakpmsyhxzlnxmdtsqqlmwnbxvmgvllafrpmlfuqpbhjddmhmbcgmlyeypkfpreddyencsdmgxysctp

【LeetCode 5】 最长回文子串

题目链接 描述 [题解] 一个讲得比较好的博客地址; 感觉manacher算法的大概思路就是利用回文串左右对称的性质. 利用之前算出来的以某个点为中心的回文串.而当前要枚举的串被包括在其中. 则可以用左半部分的结果来获取右边当前的串的结果. O(N) 当然也可以枚举中间点在哪个地方然后O(N^2)求. [代码] class Solution { public: const int N = 1000; string getSpecialString(string s){ string temp =

【最长回文子串】HDU3068最长回文【Manacher算法】

一张图领悟Manacher算法,计算字符串最长回文子串 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3068 Problem Description 给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度. 回文就是正反读都是一样的字符串,如aba, abba等 Input 输入有多组case,不超过120组,每组输入为一行小写英文字符a,b,c...y,z组成的字符串S 两组case之间由空行隔开(该空行不用处理)

[C++]LeetCode: 99 Longest Palindromic Substring (最长回文子串)

题目: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. 思路:题目要求的s的一个最长回文子串.暴力解决办法就是枚举所有的子串,再对每个子串进行回文判断.进行剪枝,我们考虑可以使用动态规划来避免重复的判

leetcode 5 :Longest Palindromic Substring 找出最长回文子串

题目: 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. 翻译: 找出字符串s中最长的回文子串,字符串s的最长是1000,假设存在唯一的最长回文子串 法一:直接暴力破解 O(N3)的时间复杂度,运行超

转载:LeetCode:5Longest Palindromic Substring 最长回文子串

本文转自:http://www.cnblogs.com/TenosDoIt/p/3675788.html 题目链接 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. 求字符串的最长回文子串 算法1:暴

计算字符串的最长回文子串 :Manacher算法介绍

在介绍算法之前,首先介绍一下什么是回文串,所谓回文串,简单来说就是正着读和反着读都是一样的字符串,比如abba,noon等等,一个字符串的最长回文子串即为这个字符串的子串中,是回文串的最长的那个. 计 算字符串的最长回文字串最简单的算法就是枚举该字符串的每一个子串,并且判断这个子串是否为回文串,这个算法的时间复杂度为O(n^3)的,显然无法令人 满意,稍微优化的一个算法是枚举回文串的中点,这里要分为两种情况,一种是回文串长度是奇数的情况,另一种是回文串长度是偶数的情况,枚举中点再判断是否 是回文

【回文字符串】 最长回文子串O(N) Manacher算法

原理讲的清晰:Manacher's ALGORITHM: O(n)时间求字符串的最长回文子串 注意: ①动态生命P[]和newStr数组后,不要忘记delete[] //其实这是基本的编码习惯 ②最终返回结果是P[i]-1 下面是自己写的Manacher函数 int manacher(char *src){ int srcLen=strlen(src); int len=2*srcLen+2; char *newStr=new char[len];//还是+3??要不要给\0留个位置??不用 i