首先大家要知道 回文数 就是正着读 和 反着读 一样的数字,区分大小写
思路1: 一般遇到极值问题,大多就是动态规划解题了
动态规划解题的关键是找到状态转移方程
我们用二维数组dp[i][j]来记录从i到j的子串是否满足回文数,那么一般就是三种情况
(1) i===j, 此时单个字符满足回文数
(2) j-i ===1 此时s[i]===s[j]才满足回文数
(3)其余情况,满足 dp[i][j]= s[i]===s[j] && dp[i+1][j-1]
这里需要注意的是数组的遍历顺序,因为dp[i][j]依赖dp[i+1][j-1],也就是依赖当前左下角的值来做判断,且在对角线位置的值一定为1,因此我们只需要遍历右上半部分。从下向上,从左到右遍历数组
/**
* @param {string} s
* @return {string}
*/
var longestPalindrome = function(s) {
let res = ''
let len = s.length
let dp = new Array(len).fill(0).map(x=>new Array(len).fill(0))
console.log(dp)
for(let i=len-1;i>=0;i--){
for(let j = i;j<len;j++){
if(i === j){
dp[i][j] = 1
}else if(j - i === 1){
if(s[i] === s[j]){
dp[i][j] = 1
}
}else{
dp[i][j] = ( s[i] === s[j] && dp[i+1][j-1] )
}
if(dp[i][j] && j-i +1 > res.length){
res = s.substring(i,j+1)
}
}
}
return res
};
思路2: 双指针
所谓回文就是指以某个字符为中心,不断向左右两边扩充相同字符,这样形成的字符串一定是回文。
那么我们只要遍历每一个字符,找出以这个字符为中心,向两边能扩散出的最长字符串并比较即可。
注意这里回文串可能有两种情况:回文串为奇数时,中心字符为1个。回文串为偶数时,中心字符为相等的两个字符,需要分别来运算
/**
* @param {string} s
* @return {string}
*/
var longestPalindrome = function(s) {
let res = ''
const len = s.length
for(let i=0;i<len;i++){
const subStr1 = longSub(i,i)
const subStr2 = longSub(i,i+1)
const temp = subStr1.length > subStr2.length?subStr1:subStr2
res = res.length>temp.length ?res:temp
}
return res
function longSub(left,right){
while(left>=0 && right <= s.length && s[left] == s[right]){
left--;
right++
}
return s.substring(left+1,right)
}
};