📜  查找最长回文 javascript 算法 - Javascript (1)

📅  最后修改于: 2023-12-03 15:10:45.581000             🧑  作者: Mango

查找最长回文 JavaScript 算法

回文是指从前往后和从后往前读都一样的字符串。例如,"racecar" 和 "level" 都是回文字符串。在字符串中查找最长回文子串是一道经典的编程问题。本文将介绍 JavaScript 中查找最长回文的算法。

算法介绍

我们可以使用动态规划算法来查找最长回文子串。该算法的基本思路是:

  • 定义一个二维数组 dp,其中 dp[i][j] 表示字符串从第 i 个字符到第 j 个字符是否为回文串。
  • i == j 时,即只有一个字符时,肯定是回文串。
  • i + 1 == j 时,即只有两个字符时,当且仅当这两个字符相等时,才是回文串。
  • i + 1 < j 时,如果子串 s[i+1, ..., j-1] 是回文串,并且 s[i] == s[j],则 s[i, ..., j] 也是回文串。

根据上述规则,我们可以得到状态转移方程:

dp[i][j] = true                           i == j
           s[i] == s[j]                    i + 1 == j
           s[i] == s[j] && dp[i+1][j-1]    i + 1 < j

最后,我们只需要在 dp 数组中找到长度最长且为回文串的子串即可。

代码实现

下面是 JavaScript 实现动态规划算法查找最长回文子串的代码:

/**
 * 查找最长回文子串
 * @param {string} s
 * @return {string}
 */
function longestPalindrome(s) {
  const n = s.length;
  const dp = Array.from({ length: n }, () => Array.from({ length: n }, () => false));
  let ans = '';
  for (let l = 0; l < n; ++l) {
    for (let i = 0; i + l < n; ++i) {
      const j = i + l;
      if (l == 0) {
        dp[i][j] = true;
      } else if (l == 1) {
        dp[i][j] = s[i] == s[j];
      } else {
        dp[i][j] = s[i] == s[j] && dp[i+1][j-1];
      }
      if (dp[i][j] && l + 1 > ans.length) {
        ans = s.substring(i, j + 1);
      }
    }
  }
  return ans;
}
测试和性能分析

下面是使用 Jasmine 对该算法进行简单测试的代码:

describe('longestPalindrome', () => {
  it('should return empty string when input is empty', () => {
    expect(longestPalindrome('')).toEqual('');
  });

  it('should return single character when input only has one character', () => {
    expect(longestPalindrome('a')).toEqual('a');
  });

  it('should return longest palindrome for odd length input', () => {
    expect(longestPalindrome('babad')).toEqual('bab');
  });

  it('should return longest palindrome for even length input', () => {
    expect(longestPalindrome('cbbd')).toEqual('bb');
  });
});

该算法的时间复杂度为 $O(n^2)$,其中 $n$ 是输入字符串的长度。具体来说,该算法需要枚举所有可能的子串,每个子串需要 $O(1)$ 的时间判断是否为回文串。该算法的空间复杂度也是 $O(n^2)$,因为需要一个二维数组来存储是否为回文串的状态。而且,由于该算法使用了动态规划的思想,算法的实现较为简单,容易理解和维护。