--算法恩仇录--实战篇--力扣(LeetCode)--005-最长回文子串--
最长回文子串这道题,最关键的步骤还是遍历字符串。如何有效的遍历字符串,是解这道题的关键。
对于回文串的遍历可以查看算法恩仇录第一章对马拉车算法的讲解:
--算法恩仇录-01-小虾米回忆马拉车--(Manacher回文串算法)
然后,接下来就只用找到原数组遍历的起点和终点就行。
JS代码如下~
1 const initString = function(str0){ 2 str = '$#'; 3 4 for(let i = 0; i<str0.length; i++){ 5 str += str0[i]; 6 str += '#'; 7 } 8 str += '*'; 9 return str; 10 } 11 const getLen = function(str){ 12 str = initString(str); 13 let len=[]; //初始化len数组 14 let rpoint=0, cpoint=-1;//rpoint为最右端的点,cpoint为回文串的中心点 15 let ans = -1,flg = -1; 16 for(let i=1; i<=str.length; i++){ 17 //当前点是否在已经匹配过的回文串中 18 //是,则取 i关于cpoint对称点的len值 和 rpoint与i的差值 19 if(rpoint > i){ 20 len[i] = Math.min(len[2*cpoint - i], rpoint - i); 21 } else { 22 //否则直接为1 23 len[i] = 1; 24 } 25 //遍历回文 26 //如果为1,说明len还未匹配这么远,重新对该点遍历 27 for(;str[i - len[i]] == str[i + len[i]];len[i]++){} 28 if(len[i] + i > rpoint) rpoint = len[i] + i,cpoint = i; 29 if(len[i] > ans){ans = len[i]-1;flg = i - len[i] + 1;flg=parseInt((flg-1)/2);} 30 } 31 //返回得到的len数组 32 //console.log(ans, flg) 33 return [ans, flg]; 34 } 35 var longestPalindrome = function(s) { 36 let [ans, flg] = getLen(s); 37 let str = ''; 38 for(let i = flg; i<flg+ans;i++){ 39 str +=s[i]; 40 } 41 //console.log(str); 42 return str; 43 };
最后结果为:
执行用时:100 ms, 在所有 JavaScript 提交中击败了90.91%的用户
内存消耗:42.1 MB, 在所有 JavaScript 提交中击败了57.85%的用户
效果拔群~
离大侠再近一步!