出題指數(最大5):⭐⭐⭐⭐⭐
題目
給定一個字符串 s,找到 s 中最長的回文子串。你可以假設 s 的最大長度為 1000。
示例 1:
輸入: "babad"
輸出: "bab"
注意: "aba" 也是一個有效答案。
示例 2:
輸入: "cbbd"
輸出: "bb"
題解
中心擴展算法——此題動態規划法的改進方法
事實上,只需使用恆定的空間,我們可以在 O(n^2)的時間內解決這個問題。
我們觀察到回文中心的兩側互為鏡像。因此,回文可以從它的中心展開,並且只有 2n - 1個這樣的中心。
你可能會問,為什么會是 2n - 1個,而不是 n個中心?原因在於所含字母數為偶數的回文的中心可以處於兩字母之間(例如“abba”
的中心在兩個b
之間)。
復雜度分析
時間復雜度:O(n^2)。由於圍繞中心來擴展回文會耗去 O(n)的時間,所以總的復雜度為 O(n^2)。
空間復雜度:O(1)。
JavaScript實現
var longestPalindrome = function(s) {
let result = "";
if(s === '') return '';
if(s.length === 1) return s;
for (let i = 0; i < s.length - 1; i++) {
// 子串長度奇數和偶數都搜索一遍
let a = maxSubstring(i, i);
let b = maxSubstring(i, i + 1);
let temp = a.length > b.length ? a : b;
result = result.length > temp.length ? result : temp;
}
return result;
// 尋找某個對稱軸為中心的最長回文子串
function maxSubstring(left, right) {
while (left >= 0 && right < s.length) {
if (s[left] === s[right]) {
left--;
right++;
}
else break;
}
// 使用slice的時候是左閉右開結構,所以left要+1指向子串第一個字符
left++;
// right到末尾使用slice會越界,單獨考慮
if (right === s.length){
// console.log('1 '+s.slice(left));
return s.slice(left);
}
// console.log('2 '+s.slice(left,right));
return s.slice(left, right);
}
};
console.log("longestPalindrome('aabacc')", longestPalindrome('aabacc')); // aba
console.log("longestPalindrome('aabaa')", longestPalindrome('aabaa')); // aabaa
console.log("longestPalindrome('cbbd')", longestPalindrome('cbbd')); //bb
做題心得
竟然一發入魂,一次提交就過了,666
js的靈活性是真的方便,函數里面可以放閉包,而且由於函數提升,還可以把閉包放在最后面,代碼整潔很多