LeetCode 热题 HOT 100 5. 最长回文子串

174 阅读1分钟

题目

题解

暴力法

我们根据回文字符串特点进行判断一个字符串是不是回文。

// 回文子串:首尾对称相等
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
};

推荐阅读

ps: 欢迎关注我的公众号 xyz编程日记,觉得不错的帮忙点个👍,点个在看。