leetcode 5. 最长回文子串:
给你一个字符串 s,找到 s 中最长的回文子串。
输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。
输入:s = "cbbd"
输出:"bb"
- 使用中心扩散算法。
比如我们要匹配的字符串是abcde
,首先我们需要遍历每个元素,把每个元素当成中心点,比如我们先把a当成中心点,然后判断a左侧的值和a右侧的值是否相等,如果相等,那么在看a左侧的左侧和a右侧的右侧的值是否相等,按照这种方法直到不相等,当然不相等的情况可能是超出了字符串的边界或者真的不相等,然后记录这个以a为中心的回文子串到底多长,然后在和目前最长的作比较,以这样的方式遍历所有字符串,也就是以这样的方式先遍历a,然后是b,然后是c,d,e。最终得到最长的回文串。
这里我们有两个注意点:
(1) 如何判断不相等的情况,也就是如何判断边界和确实不相等
(2) 我们刚刚说的是以一个点为中心,向着两边扩散,这样匹配的结果一定是奇数的,那么偶数情况该如何判断?这个我们需要分别处理。
时间复杂度O( n 2 n^2 n2):这里大家可能会有疑问,为什么时间复杂度是 n 2 n^2 n2呢,最外面的一层for循环是n应该都了解,但是为什么里面的也是n呢?,因为里面的while循环每次都没有走满n,顶多是n的一半,那么为什么是 n 2 n^2 n2呢?这里给大家一些提示,如果一个算法正儿八经算出来的时间复杂度是 n 2 / 10000 n^2/10000 n2/10000,那么这个算法时间复杂度该怎么表示?应该还是表示成 n 2 n^2 n2对吧,因为n无限大,分母就可以忽略了。如果还是不是太懂,可以看我这篇文章中心扩散算法时间复杂度为什么是n2解析
空间复杂度O(1)
var longestPalindrome = function(s) {
let length = s.length
let str = ""
for(let i = 0; i < s.length; i++){
let left = right = i
changeCurrentPalindrome(left, right)
left = i, right = i + 1
changeCurrentPalindrome(left, right)
}
function changeCurrentLongestPalindrome(left, right){
while(s[left] === s[right]){
left--
right++
if(left < 0 || right >= length) break
}
if(right - left - 1 > str.length) str = s.slice(left + 1, right)
}
return str
};