返回

JavasScript解析最长回文子串

前端

在编程世界中,处理字符串是不可避免的。字符串的有趣之处在于它可以包含各种字符,形成不同的组合,而回文子串是字符串中一种独特的模式。回文子串是指一个字符串正着读和反着读都相同的子串,例如“radar”和“level”。

在本文中,我们将重点探讨如何使用JavaScript找出字符串中最长的回文子串。我们将从暴力枚举法开始,逐步优化代码,最终实现一个高效的算法。

暴力枚举法

暴力枚举法是最简单直接的方法,它枚举所有可能的子串,并检查每个子串是否是回文。如果一个子串是回文,我们将记录它的长度和位置。最终,我们将输出最长的回文子串。

function longestPalindrome(s) {
  let maxLen = 0;
  let maxStr = "";
  for (let i = 0; i < s.length; i++) {
    for (let j = i + 1; j <= s.length; j++) {
      const subStr = s.substring(i, j);
      if (isPalindrome(subStr) && subStr.length > maxLen) {
        maxLen = subStr.length;
        maxStr = subStr;
      }
    }
  }
  return maxStr;
}

function isPalindrome(str) {
  return str === str.split('').reverse().join('');
}

暴力枚举法的复杂度为O(n^3),其中n是字符串的长度。这是因为我们需要枚举所有可能的子串,并检查每个子串是否是回文。

中心扩展法

中心扩展法是一种更加高效的算法。它从字符串的中间开始,向两边扩展,检查字符是否相同。如果字符相同,我们将继续扩展;如果字符不同,我们将停止扩展,并记录当前的最长回文子串。

function longestPalindrome(s) {
  let maxLen = 0;
  let maxStr = "";
  for (let i = 0; i < s.length; i++) {
    expandAroundCenter(s, i, i, maxLen, maxStr);
    expandAroundCenter(s, i, i + 1, maxLen, maxStr);
  }
  return maxStr;
}

function expandAroundCenter(s, left, right, maxLen, maxStr) {
  while (left >= 0 && right < s.length && s[left] === s[right]) {
    const subStr = s.substring(left, right + 1);
    if (subStr.length > maxLen) {
      maxLen = subStr.length;
      maxStr = subStr;
    }
    left--;
    right++;
  }
}

中心扩展法的复杂度为O(n^2),因为我们只需要检查每个字符一次。

马拉车算法

马拉车算法是中心扩展法的一种优化。它使用一个预处理数组来记录每个字符的回文半径,从而减少了比较的次数。

function longestPalindrome(s) {
  const n = s.length;
  let p = new Array(n).fill(0);
  let maxLen = 0;
  let maxStr = "";
  for (let i = 0; i < n; i++) {
    expandAroundCenter(s, i, i, maxLen, maxStr, p);
    expandAroundCenter(s, i, i + 1, maxLen, maxStr, p);
  }
  return maxStr;
}

function expandAroundCenter(s, left, right, maxLen, maxStr, p) {
  while (left >= 0 && right < s.length && s[left] === s[right]) {
    const subStr = s.substring(left, right + 1);
    if (subStr.length > maxLen) {
      maxLen = subStr.length;
      maxStr = subStr;
    }
    p[left] = right - left + 1;
    p[right] = right - left + 1;
    left--;
    right++;
  }
}

马拉车算法的复杂度为O(n),因为预处理数组只需要计算一次,而且每个字符只会被检查一次。

结语

在本文中,我们探讨了如何使用JavaScript找出字符串中最长的回文子串。我们从暴力枚举法开始,逐步优化代码,最终实现了马拉车算法,这是一个高效的O(n)算法。

希望本文能帮助您更好地理解回文子串算法,并将其应用到您的项目中。如果您有任何问题或建议,请随时留言。