返回

破解LeetCode 524:通过删除字符匹配字典中的最长单词

前端

算法剖析

LeetCode 524 考验了我们对字符串处理和动态规划的理解。给定一个字符串 s 和一个字典 dictionary,我们需要找到字典中最长的字符串,可以通过删除 s 中的某些字符而得到。

动态规划

解决此问题的核心思想是动态规划,它是一种将问题分解成更小的子问题,并逐步构建解决方案的技巧。具体而言,我们将创建一个二维表 dp,其中 dp[i][j] 表示 s[0:i] 的子字符串可以匹配 dictionary[0:j] 的子字符串的最大长度。

状态转移

对于 dp 表中的每个单元格 dp[i][j],我们可以根据以下规则进行计算:

  • 如果 s[i] = dictionary[j],则 dp[i][j] = dp[i-1][j-1] + 1,表示我们匹配了下一个字符。
  • 否则,dp[i][j] = max(dp[i-1][j], dp[i][j-1]),表示我们尝试删除 s[i] 或 dictionary[j] 中的字符。

寻找最长单词

我们完成了 dp 表的构建后,需要遍历 dp 的最后一行来寻找最长的匹配长度。

max_len = 0
for j in range(len(dictionary)):
    max_len = max(max_len, dp[len(s)-1][j])

代码实现

下面提供了一个 Python 解决方案:

def find_longest_word(s, dictionary):
    # 初始化 dpdp = [[0] * (len(dictionary) + 1) for _ in range(len(s) + 1)]

    # 构建 dpfor i in range(1, len(s) + 1):
        for j in range(1, len(dictionary) + 1):
            if s[i-1] == dictionary[j-1]:
                dp[i][j] = dp[i-1][j-1] + 1
            else:
                dp[i][j] = max(dp[i-1][j], dp[i][j-1])

    # 寻找最长匹配长度
    max_len = 0
    for j in range(len(dictionary)):
        max_len = max(max_len, dp[len(s)-1][j])

    # 返回最长单词
    for j in range(len(dictionary)):
        if dp[len(s)-1][j] == max_len:
            return dictionary[j]

    return ""

复杂度分析

  • 时间复杂度:O(m * n),其中 m 和 n 分别是字符串 s 和字典 dictionary 的长度。
  • 空间复杂度:O(m * n),用于存储 dp 表。

总结

通过删除字符匹配字典中的最长单词问题体现了算法思维和动态规划技巧的结合。理解状态转移方程并正确构建 dp 表对于解决此类问题至关重要。希望本文的详细解释和代码示例有助于你全面掌握这一算法。