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.
这个题目是一个很常见的面试题,有暴力穷举法,最长前缀法,还有一个非常巧妙的方法,manacher's algorithm, 看到这个算法的时候,发现真的是太优美了,不得不佩服设计出这个算法的人。
本文参考了这篇文章:http://blog.csdn.net/ggggiqnypgjg/article/details/6645824
先假设
1) 数组为S,题目中的数组
2) 辅助数组T,T数组是在数组S的每个元素前后插入一个“#”,例如
S = “caba”, 那么 T = "#c#a#b#a#"
S = "bb", 那么 T = “#b#b#”
3) 数组P,其中P[i] 表示以T[i] 为中心的回文串从T[i]到串边界的长度,有点拗口,看个例子, 例如
S=“bb”,那么T="#b#b#",
P[0] = 1 T[0] = "#" , 回文串为 “#",#长度为1
P[1] = 2 T[1] = "b", 回文串为"#b#",b#长度为2
P[2] = 3 T[2] = "#", 回文串为"#b#b#", #b#长度为3
4) id, mx, 其中 P[id] = mx, 表示最大回文串,那么这个串的起始索引是[id-mx+1], 终点索引是[id+mx-1]
例如3)里面,id = 2, mx = 3, 起始索引是id-mx+1 = 2-3+1=0,终点索引是id+mx-1=2+3-1=4
OK, 下面是程序(java实现)
public static String longestPalindrome(String s) { if(s==null || s.length() == 0){ return ""; } if(s.length() == 1){ return s; } String T = prePocess(s); int i; int mx = 0; int id = 0; int[] P = new int[T.length()]; for(i=1;i<T.length();i++){ if(mx > i){ P[i] = Math.min(P[2*id - i],mx-i); }else{ P[i] = 1; } while((i+P[i]<T.length()) && (i-P[i])>=0 && T.charAt(i+P[i]) == T.charAt(i-P[i])){ P[i]++; } if(P[i]>mx){ mx = P[i]; id = i; } } return T.substring(id-mx+1,id+mx-1).replace("#", ""); } public static String prePocess(String s){ StringBuffer sb = new StringBuffer(); for(int i=0;i<s.length();i++){ sb.append("#").append(s.charAt(i)); } return sb.toString()+"#"; }
好了,让我们来看一下,最神奇的几行代码
if(mx > i){
P[i] = Math.min(P[2*id - i],mx-i);
}else{
P[i] = 1;
}
看到 P[i] = Math.min(P[2*id - i],mx-i); 首先我心中有三个疑问:
1. P[i] 为什么比 mx - i 小?
2. P[i] 为什么比 P[2*id - i] 小?
3. P[i] 为什么取这二者的最小者?
其实是个折中,
首先,以i为中心,向右延伸mx-i长度的回文串肯定落在以id为中心,向右延伸mx长度的回文串里面。
我们只能在这个范围里面比较,因为超过id+mx的元素,还没有被比较过,所以限定这个范围,
那么在这个范围内,由于回文串的特点,以id为中心左右折叠是重合的,所以寻找i以id为中心的对称位置,
即2*id - i,而这个位置我们已经得到结果即P[2*id-i], 但是不能直接取P[2*id-i], 因为P[2*id-i] 可能会大于mx-i,如果大于的话,那么就不在可控范围了,所以最后取二者最小值。
P.S:这个题目经常我面试阿里巴巴实习生的时候被面到过,当时不知道manacher's algorithm,所以只给了穷举算法,囧。
相关推荐
LeetCode的第五题要求我们找到给定字符串中最长的回文子串。 解决这个问题,可以采用多种方法,比如动态规划、中心扩散或Manacher's Algorithm。这里我们主要关注动态规划的方法,因为它是理解和实现相对简单的途径...
Manacher's 算法是一种高效解决字符串中最长回文子串问题的算法,它能在O(n)的时间复杂度内完成,其中n是字符串的长度...在LeetCode等在线编程平台上,该算法常用于解决字符串处理问题,特别是求解最长回文子串的问题。
第5题“最长回文子串”是LeetCode中的一个经典问题,它涉及到字符串处理和动态规划等核心编程概念。在这个题解中,我们将深入探讨如何用C++解决这个问题。 首先,我们要理解什么是回文子串。一个回文串是正读反读都...
1. 动态规划(DP)算法在解决最长回文子串问题中的应用 ...本文讨论了动态规划算法在解决最长回文子串问题中的应用,并详细介绍了回文串和最长回文子串的定义和性质,以及 C++ 语言和字符串处理的相关知识。
原创:leetcode 5. 最长回文子串//寻找以i-1,i为中点偶数长度的回文//寻找以i为中心的奇数长度的回文。
leetcode刷题宝典
Leetcode 1312. 让字符串成为回文串的最少插入次数问题描述1312. 让字符串成为回文串的最少插入次数 - 力扣(LeetCode)算法解法1: 递
其中,第5题“最长回文子串”是经典的字符串处理问题,对于Java程序员来说,理解和解决这个问题至关重要。下面将详细探讨这个题目以及相关的Java编程知识点。 **题目描述:** 给定一个字符串`s`,找到`s`中的最长...
在LeetCode的第5题《最长回文子串》中,目标是找到给定字符串` s `中的最长回文子串。回文串是指正读反读都能读通的字符串,例如 "aba" 和 "abba" 都是回文串。本题要求的解决方案需在字符串长度不超过1000的限制内...
最长回文子串"是其中一道经典的字符串处理问题,目标是从给定的字符串中找出最长的回文子串。回文串是指正读反读都能读通的字符串,例如 "abcba" 和 "abccba"。 这道题目给出了一些示例,例如输入字符串 "babad",...
在给定的字符串中寻找最长的回文子串,可以是一项具有挑战性的任务,尤其是在处理大型字符串时。 解决这个问题的一个经典算法是Manacher's Algorithm,它可以在O(n)的时间复杂度内完成,其中n是字符串的长度。不过...
Longest-Palindromic-Substring(最长回文子串) 给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。 Sample 1 输入: "babad" 输出: "bab" 注意: "aba" 也是一个有效答案。 Sample 2 输入...
最大公共字符串leetcode 最长回文子串 给定一个字符串 s,找出 s 中最长的回文子串。 您可以假设 s 的最大长度为 1000。 Example 1: Input: "babad" Output: "bab" Note: "aba" is also a valid answer. Example 2: ...
3 初始值和特殊情况由于常规情况要求$$j-1\geq i+1$$,所以字符串只有两个字母或者一个字母的情况要特殊考虑一个字母的情况,肯定是回文串:两个字母的情
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。 示例 1: 输入: “babad” 输出: “bab” 注意: “aba” 也是一个有效答案。 示例 2: 输入: “cbbd” 输出: “bb” 思路 基于中心...
回文串是一个特殊的字符串,它的...Manacher's Algorithm尤其在处理长字符串时效率较高,因为它能够在线性时间内找到最长回文子串。但对于LeetCode的这个题目,由于字符串长度的限制,上述简单的计数方法已经足够了。
最长回文子串 (251_Medium) LeetCode 6 : ZigZag 对话 (15_Medium) LeetCode 7 : 反转整数 (174_Easy) LeetCode 9 : 回文数 (248_Easy) LeetCode 11 : 盛水最多的容器 (5_Medium) LeetCode 12 : 整数转罗马 (30_...
回文子串问题是一个经典的计算机科学问题,主要目标是从给定的字符串中找出最长的回文子串。回文子串是指在正读和反读时都相同的字符串,例如"aba"、"abcba"等。 该问题可以采用多种方法解决,其中最常见的是动态...
1. **预处理**:首先,构建一个哈希表,存储每个字符串的回文子串及其起始位置。回文子串是指从左到右和从右到左读都一样的子串。这样,我们可以快速查找到某个字符是否能与另一个字符串的另一部分组成回文。 2. **...