返回

前端面试必会:巧解最长回文子串算法

前端

最长回文子串:高效算法指南

作为一名前端工程师,在算法面试中驾驭最长回文子串问题至关重要。这篇文章将深入探讨两种经典算法:马拉车算法和动态规划算法。掌握这些算法将让你在面试中脱颖而出,增强你的算法技能。

什么是最长回文子串?

回文子串是指一个字符串,无论正读还是反读都是相同的。例如,"racecar" 和 "abcba" 都是回文子串。最长回文子串问题要求我们找到给定字符串中最长的回文子串。

马拉车算法:从中心向外扩展

马拉车算法从字符串的每个字符出发,向两侧扩展,寻找最长的回文子串。

  1. 从中心开始: 从字符串的每个字符出发,向左和向右扩展,直到遇到不同字符或字符串边界。
  2. 记录长度: 记录每个字符为中心的回文子串的长度。
  3. 选择最长: 选择所有记录长度中最大的那个,即为最长回文子串的长度。

代码示例:

def longest_palindrome(s):
    max_len = 1
    start = 0
    end = 0

    for i in range(len(s)):
        odd_len = expand_around_center(s, i, i)
        if odd_len > max_len:
            max_len = odd_len
            start = i - (odd_len - 1) // 2
            end = i + (odd_len - 1) // 2

        even_len = expand_around_center(s, i, i + 1)
        if even_len > max_len:
            max_len = even_len
            start = i - (even_len - 2) // 2
            end = i + (even_len - 2) // 2

    return s[start:end + 1]


def expand_around_center(s, left, right):
    while left >= 0 and right < len(s) and s[left] == s[right]:
        left -= 1
        right += 1
    return right - left - 1

动态规划算法:逐个子问题解决

动态规划算法将原问题分解为一系列子问题,逐个求解并记录结果。

  1. 初始化: 初始化一个二维数组 dp,其中 dp[i][j] 表示字符串 s[i:j] 的最长回文子串长度。
  2. 基础情况: 对于所有 i,dp[i][i] = 1(长度为 1 的子字符串都是回文子串)。
  3. 递推公式: 对于长度大于 1 的子字符串 s[i:j],如果 s[i] 等于 s[j],则 dp[i][j] 等于 dp[i+1][j-1] 加 2。否则,dp[i][j] 等于 dp[i+1][j-1](不包括 s[i] 和 s[j])。
  4. 结果: 最长回文子串的长度为 dp[0][n-1],其中 n 是字符串的长度。

代码示例:

def longest_palindrome(s):
    n = len(s)
    dp = [[0] * n for _ in range(n)]

    max_len = 1
    start = 0

    # 初始化对角线
    for i in range(n):
        dp[i][i] = 1

    # 填充对角线右侧的元素
    for i in range(n - 1):
        if s[i] == s[i + 1]:
            dp[i][i + 1] = 2
            max_len = 2
            start = i

    # 填充对角线左侧的元素
    for k in range(3, n + 1):
        for i in range(n - k + 1):
            j = i + k - 1
            if s[i] == s[j] and dp[i + 1][j - 1] >= k - 2:
                dp[i][j] = k
                if k > max_len:
                    max_len = k
                    start = i

    return s[start:start + max_len]

案例分析

考虑字符串 "abccba":

  • 马拉车算法:从 'a' 开始扩展得到 "a",从 'b' 开始扩展得到 "bb",从 'c' 开始扩展得到 "ccc",从 'c' 和 'b' 开始扩展得到 "ccbc",从 'a' 和 'c' 开始扩展得到 "aca",从 'a' 和 'b' 开始扩展得到 "aba"。最长回文子串为 "ccbc",长度为 4。
  • 动态规划算法:初始化 dp 数组,对角线元素为 1。对角线右侧的元素为 2("bb"),对角线左侧的元素为 4("ccbc")。最长回文子串的长度为 4,起始位置为 1(字符串的第二个字符)。

结论

马拉车算法和动态规划算法都是求解最长回文子串问题的有力工具。马拉车算法更直观,但动态规划算法具有更低的时间复杂度。选择最合适的算法取决于输入字符串的长度和算法的性能要求。通过理解这些算法的原理和应用,你将能够自信地解决算法面试中的最长回文子串问题。

常见问题解答

  1. 什么时候使用马拉车算法?
    当输入字符串较短时,马拉车算法往往是更快的选择。
  2. 什么时候使用动态规划算法?
    当输入字符串较长时,动态规划算法更有效,因为它具有较低的时间复杂度。
  3. 哪种算法更难理解?
    动态规划算法的递推公式可能需要一些时间来理解,但总体而言,两种算法都可以相对容易地理解。
  4. 这些算法的应用场景是什么?
    最长回文子串算法在文本处理、DNA 序列分析和密码学等领域有着广泛的应用。
  5. 如何提高我的算法技能?
    持续练习、研究不同算法的原理,并参加算法编码挑战,以提高你的算法技能。