题目
题解
暴力法
我们根据回文字符串特点进行判断一个字符串是不是回文。
// 回文子串:首尾对称相等const isPalindrome = s => { // abba aba for (let i = 0; i < Math.floor(s.length / 2); i++) { if (s[i] !== s[s.length - 1 - i]) { return false } } return true}/** * @param {string} s * @return {string} */var longestPalindrome = function(s) { let answer = '' if (s.length <= 1) return s[0] || '' for (let i = 0; i < s.length - 1; i++) { for (let j = i + 1; j <= s.length; j++) { curStr = s.substring(i, j) if (curStr.length > answer.length && isPalindrome(curStr)) { answer = curStr } } } return answer};
动态规划
•一个回文字符串 abdba 去掉首尾后仍是回文 bdb•由此推导状态转移方程 dp•dp[i][j] 表示 s.substring(i, j+1) 这样一个字符串是不是回文字符串•dp[i][j] = (s[i] === s[j]) && dp[i+1][j-1]•dp[i+1][j-1] 即就表示去掉首位字符后•我们还需要考虑一个特殊情况 类似 a ab aba 肯定存在回文串 即 j - i <= 2•动态规划就是充分利用之前缓存的计算结果,快速推倒出一个字符串是不是一个回问文串•动态规划也是典型的 空间换时间的一种思路
/** * @param {string} s * @return {string} */var longestPalindrome = function(s) { const len = s.length let answer = '' const dp = Array.from(new Array(len), () => new Array(len).fill(false)) // 此处可以省略 base state 初始化 dp[i][j] = true for (let i = len - 1; i >= 0; i--) { for (let j = i; j < len; j++) { // 状态转移方程 dp[i][j] = (s[i] === s[j]) && (j - i <= 2 || dp[i+1][j-1]) // 更新最长子串 if (dp[i][j]) { console.log(s.substring(i, j + 1)) } if (dp[i][j] && (j - i >= answer.length)) { answer = s.substring(i, j + 1) } } }// console.log(dp) return answer};
推荐阅读
•告别动态规划,连刷 40 道题,我总结了这些套路,看不懂你打我(万字长文)[1]•如何理解动态规划?[2]
ps: 欢迎关注我的公众号 xyz编程日记,觉得不错的帮忙点个?,点个在看。
References
[1]
告别动态规划,连刷 40 道题,我总结了这些套路,看不懂你打我(万字长文): https://zhuanlan.zhihu.com/p/91582909[2]
如何理解动态规划?: https://www.zhihu.com/question/39948290