const readline = require('readline'); const rl = readline.createInterface({ input:process.stdin, output:process.stdout }); rl.on('line',(line) => { console.log(longestPalindrome(line)) })
方法一:暴力法
思路:首先写出一个判断是否为回文串的工具函数。从头开始,不断增加字符判断每一个字符是否回文,并判断当前会问长度是否大于之前记录的最长回文串的长度,如果大于则更新回文串。
charAt() 方法可返回指定位置的字符
请注意,JavaScript 并没有一种有别于字符串类型的字符数据类型,所以返回的字符是长度为 1 的字符串。
请注意,JavaScript 并没有一种有别于字符串类型的字符数据类型,所以返回的字符是长度为 1 的字符串。
注意:力扣提示超时,牛客居然不超时???
const longestPalindrome = (s) => { let longS = ''; let nowS = ''; for(let i =0; i < s.length; i++){ nowS = ''; for(let j = i; j <s.length;j++){ nowS += s.charAt(j); if(isPalindrome(nowS) && nowS.length > longS.length){ longS = nowS; } } } return longS.length; }; const isPalindrome = (s) => { return s === s.split('').reverse().join(''); }
方法二:中心扩展法
思路:首先,先写出一个中心扩展函数。主要作用:类似于双指针移动。此函数的参数有三个,分别是字符串、左指针以及右指针。循环以下过程:如果某子串(初始为某点,任意位置,即中心点)是回文串,左右指针分别指向头和尾,左右指针分别向左右移动一位,若相等,则说明新的子串是更长的回文串。若不等,则不再为回文串,返回刚才回文串的长度。
const longestPalindrome = (s) => { let start = 0, end = start; for(let i = 0 ; i < s.length; i++){ let len1 = search(s,i,i); let len2 = search(s,i,i+1); let len = Math.max(len1,len2); if(len > end - start){ start = i - Math.floor((len - 1)/ 2); end = i + Math.floor(len/2); } } return s.slice(start, end +1).length }; const search = (s,l,r) => { let left = l; let right = r; while(left >= 0 && right < s.length && s[left] === s[right]){ left--; right++; } return right - left -1; }优化版:贪心+双指针
const longestPalindrome = (s) => { let max = 0;// 当前最大回文串的长度 let start = -1;// 当前最大回文串的起始索引 for(let i=0;i < s.length; i++){ let now = 1;// 当前回文串的长度 let l = i - 1;// 左侧开始遍历的指针 while(s[i+1] === s[i]){// 如果当前字符后边的字符都一样, 当前长度 + 1, s遍历指针向后推 now++; i++; } let r = i +1;// 获取右侧开始遍历的指针 while(s[l]===s[r] && s[l] !== undefined){ // 从连续字符两端开始像两侧扩展,直到越界或者不一致,一致的直接累积到当前长度中,修改左右指针 now += 2; l--; r++; } if(now > max){ // 判断与之前最大的对比,更新当前最大回文串的起始索引 max = now; start = l +1 } } return s.slice(start,start+max).length;// 通过最大长度和起始索引,获取需要的字符串 };