Longest Palindromic Substring
Total Accepted: 17474 Total Submissions: 84472 My SubmissionsGiven 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.
先解释一下题目的意思:
题目要求字符串的回文子字符串,所谓的回文字符串就是从左向右读和从右向左读都一样的字符串,例如:“abcba”或者“abba”
题目还假设字符串的最大长度为1000,而且有且只有一个最大的回文子字符串。
从上面的例子可知,回文字符串有奇偶之分,我们在字符串中插入特殊字符,把偶的情况也作为奇的情况处理:
例:abc -> @#a#b#c#$ (头尾插入不同的特殊字符是为了防止越界)
最简单的方法:
遍历字符串,使用一个数组prad[ ],prad[ i ]保存以第 i 个字符为中心的回文字符串的半径(这个新字符串的半径就刚好等于原字符串的长度)
然后再遍历这个数组就可以轻易得到子回文字符串了:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44class Solution { public: string change(string s) { string result = "!"; for (int i = 0; i < s.length(); i++) { result += "#"; result += s[i]; } result += "#?"; return result; } string longestPalindrome(string s) { if (0 == s.length()) { return ""; } string new_s = this->change(s); int size = new_s.length(); int* prad = new int[size]; for (int i = 1; i < size - 1; i++) { prad[i] = 0; while (new_s[i - prad[i] - 1] == new_s[i + prad[i] + 1]) { prad[i]++; } } int maxLen{}, start_pos{}; for (int i = 1; i < size - 1; i++) { if (maxLen < prad[i]) { maxLen = prad[i]; start_pos = (i - maxLen - 1) / 2; } } delete[]prad; return s.substr(start_pos, maxLen); } };
该算法的复杂度是O(n2),每一次都重新匹配太浪费时间了,我们可以利用前面匹配得到的信息,将下次匹配的范围缩小一点,这就是传说中的Manacher算法:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57class Solution { public: string change(string s) { string result = "!"; for (int i = 0; i < s.length(); i++) { result += "#"; result += s[i]; } result += "#?"; return result; } string longestPalindrome(string s) { if (0 == s.length()) { return ""; } string new_s = this->change(s); int size = new_s.length(); int* prad = new int[size]; int right_end{}, pos{};//记录匹配到的回文字符串达到的最右边,和该字符串的中心位置 for (int i = 1; i < size - 1; i++) { if (right_end > i) { prad[i] = min(right_end - i, prad[2 * pos - i]); } else { prad[i] = 0; } while (new_s[i - prad[i] - 1] == new_s[i + prad[i] + 1]) { prad[i]++; } if (i + prad[i] > right_end) { right_end = i + prad[i]; pos = i; } } int maxLen{}, start_pos{}; for (int i = 1; i < size - 1; i++) { if (maxLen < prad[i]) { maxLen = prad[i]; start_pos = (i - maxLen - 1) / 2; } } delete[]prad; return s.substr(start_pos, maxLen); } };
最后
以上就是闪闪巨人最近收集整理的关于【Leet Code】Longest Palindromic Substring ——传说中的Manacher算法的全部内容,更多相关【Leet内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复