返回

前端面试秘籍:每日 3+1 冲刺第688天

见解分享

前端面试每日 3+1

大家好,我是 jsliang。在前端面试每日 3+1 系列文章中,我将每天分享一道前端面试题目,并提供详细的解题思路和代码示例。今天是第 688 天,我们一起来解决一道关于算法和数据结构的问题。

题目

给定一个字符串,找出其中最长的回文子串。

示例:

输入:s = "babad"
输出:"bab"

输入:s = "cbbd"
输出:"bb"

解题思路

这个问题可以使用动态规划来解决。我们定义一个二维数组 dp,其中 dp[i][j] 表示从字符串 s 的第 i 个字符到第 j 个字符的子串是否是一个回文串。

我们从字符串的末尾开始,逐个计算 dp[i][j] 的值。对于 dp[i][j],如果 s[i] == s[j],并且 dp[i+1][j-1] 为真(即从第 i+1 个字符到第 j-1 个字符的子串是一个回文串),那么 dp[i][j] 也为真。否则,dp[i][j] 为假。

最后,我们找到 dp 数组中所有为真的最大子矩阵,该子矩阵所对应的子串就是最长的回文子串。

代码示例

/**
 * 找出字符串中最长的回文子串
 *
 * @param {string} s 输入字符串
 * @return {string} 最长的回文子串
 */
const longestPalindrome = (s) => {
  if (!s || s.length < 2) {
    return s;
  }

  // 初始化 dp 数组
  const dp = new Array(s.length).fill(0).map(() => new Array(s.length).fill(false));

  // 从后往前计算 dp 数组
  for (let i = s.length - 1; i >= 0; i--) {
    dp[i][i] = true;
    for (let j = i + 1; j < s.length; j++) {
      if (s[i] === s[j]) {
        if (j - i <= 2) {
          dp[i][j] = true;
        } else {
          dp[i][j] = dp[i + 1][j - 1];
        }
      }
    }
  }

  // 找出最大的回文子串
  let startIndex = 0;
  let maxLength = 0;
  for (let i = 0; i < s.length; i++) {
    for (let j = i; j < s.length; j++) {
      if (dp[i][j] && j - i + 1 > maxLength) {
        startIndex = i;
        maxLength = j - i + 1;
      }
    }
  }

  return s.substring(startIndex, startIndex + maxLength);
};

总结

这道题目考察了动态规划和字符串处理的能力。通过使用二维数组 dp 来存储子串是否为回文串的信息,我们可以高效地找出最长的回文子串。