作为一个前端算法真的很一般,看了别人的计算方法要不是java c++ 要不就是描述算法看起来很吃力。
于是用 js 重写了一个方法,并且在过程中添加了详细的注释。
const s = 'abcd123dcbaaba11' // 长度16
function lp(s) {
let lplang = 1 // 最长长度
let start = 0 // 当最长长度更新时同时缓存起始点
let len = s.length
let dp = [] // 缓存结果
// 长度 1 2 单独处理
for(let i=0; i<len; i++) {
if(dp[i] === undefined) {
dp[i] = [] // 初始化二维数组
}
dp[i][i] = true // 自己是自己的回文
// 找出长度为2的回文
if(s[i] === s[i+1]) {
dp[i][i+1] = true // 缓存结果
start = i
lplang = 2 // 比如两个连续的 aa 也是回文,并且标记最长长度
}
}
// 动态规划 找最优子,比如 aa 是回文,那么 baab 只需要判断 b === b && (aa: 缓存的结果)
// L 为子串长度,首先找出长度为3的回文,然后是4,5...
// 同时通过 L 计算 子串终点 i+L-1,起始点+长度-1 = 终点
for(let L=3; L<=len; L++) {
for(let i=0; i+L-1<len; i++) {
// 越往后便利次数越少 当L是16的时候 只遍历1次 判断s[0]s[15]是否相等
let j = i+L-1 // 第一次对比的是 s[0] === s[2]
if(s[i] === s[j] && dp[i+1][j-1]) {
// 两头相等 并且 子是回文
dp[i][j] = true // 缓存结果 先缓存的是所有的最短的子串结果
start = i
lplang = L // 因为L是从小到大便利的 所以后面的回文长度就是最长的
}
}
}
return s.substr(start,lplang)
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。