leetcode Problem 5 最长子回文串
来源:互联网 发布:詹姆斯生涯场均数据 编辑:程序博客网 时间:2024/06/05 16:31
题目:Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.
1、暴力做法。
遍历所有的子串,求出最长。复杂度O(n3)。显然GG了。
2、动态规划
把一个大问题分解成每一个小问题进行求解。假设字符串s,则s[i]到s[j]是回文的话,s[i+1]到s[j-1]也是回文;或者说,已知s[i+1]到s[j-1]是回文的情况下,如果s[i]==s[j]则,s[i]到s[j]就是回文,我们用数组table[i][j]来表示i到j的是否回文状态。代码如下,复杂度是o(n2)。
var longestPalindrome = function (s) { const length = s.length; let table = []; for (let i = 0; i < 1000; i++) { table[i] = new Array(); for (let j = 0; j < 1000; j++) { table[i][j] = 0; } } let maxlength = 1, maxstr, longestbegin; for (let i = 0; i < length; i++) { table[i][i] = 1; //所有的 i 到 i的字符串是回文 longestbegin = i; } for (let i = 0; i < length - 1; i++) { //长度为2的回文 if (s[i] === s[i + 1]){ table[i][i + 1] = 1; maxlength = 2; longestbegin = i; } } //状态转移 再table[i+1][j-1] == 1的情况下,如果i === j,则 table[i][j]为1 从长度为3的回文开始 for (let len = 3; len <= length; len++) { for (let i = 0; i < length - len + 1; i++) { //遍历所有长度为len的字符串 let j = i + len - 1;//两种情况 单数回文和双数回文 //let j = len % 2 === 0?i + len - 2 if (s[i] === s[j] && table[i + 1][j - 1] === 1) { table[i][j] = 1; maxlength = len; longestbegin = i; } } } //console.log(longestbegin, maxlength) return s.slice(longestbegin,longestbegin + maxlength)};
然而,这里还是过不了leetcode的。显然,还需要优化的地方
好像o(n2)也是能强行过的。。把字符串换成数组再处理。不过时间只优于百分之1的人,太菜了23333
//最长回文串 o(n2)var longestPalindrome = function (s) { const length = s.length; s = s.split(''); let table = []; let maxlength = 1, maxstr, longestbegin = 0; for (let i = 0; i < length; i++) { table[i] = new Array(); table[i][i] = 1; } for (let i = 0; i < length - 1; i++) { //长度为2的回文 if (s[i] === s[i + 1]) { table[i][i + 1] = 1; maxlength = 2; longestbegin = i; } } //状态转移 再table[i+1][j-1] == 1的情况下,如果i === j,则 table[i][j]为1 从长度为3的回文开始 for (let len = 2; len <= length; len++) { for (let i = 0; i < length - len + 1; i++) { //遍历所有长度为len的字符串 let j = i + len - 1; //两种情况 单数回文和双数回文 //let j = len % 2 === 0?i + len - 2 if (s[i] === s[j] && table[i + 1][j - 1] === 1) { table[i][j] = 1; maxlength = len; longestbegin = i; } } } //console.log(longestbegin, maxlength) return s.join('').slice(longestbegin, longestbegin + maxlength)//真的是日了狗。。。数组处理比字符串处理要快};
而且不是每次都能过,这个还是要优化的啊
换另一种思路,就是。遍历字符串中的每个字符。算出以该字符为中心的最长回文串
var longestPalindrome2 = function (s) { function expandAroundCenter(s, l, r) { while (l >= 0 && r < sLen && s[l] == s[r]) { l--; r++; } return r - l - 1; } let start = 0, end = 0, len1 = 0, len2 = 0, len = 0, sLen = s.length; for (let i = 0; i < sLen; i++) { len1 = expandAroundCenter(s, i, i);//aba这种回文 len2 = expandAroundCenter(s, i, i + 1);//abba这种回文 len = Math.max(len1, len2);//算出较大的回文 if (len > end - start) { end = i + (len >> 1); start = end + 1 - len; } } return s.substring(start, end + 1);};
这次就快多了。。。。
阅读全文