返回

追溯本质,删繁就简:LeetCode 524 寻找字典里最长单词的捷径

见解分享

LeetCode 524 这道题乍看之下似乎复杂难懂,但如果你能够剥离表象,追溯其本质,就会发现它其实是一次对字符串处理能力的考验。在有限的字符资源下,我们该如何组装出最长的单词?这便是这道题的核心所在。

解题的诀窍在于,我们将把字符串s视作原料,而字典则是一个工具箱。我们的目标是利用字典这个工具箱,通过添加、删除或替换字符,最终在s中拼出最长的单词。

1. 确定问题本质:匹配最长单词

要找到字典中能匹配s的最长单词,我们可以考虑这样一种方法:

  • 将字典中的单词按照长度从大到小排序。
  • 对于每个单词,检查它是否是s的子序列。如果是,则它就是我们所要找的单词。

2. 寻找最长单词:动态规划的妙用

当我们确定了问题的本质后,就可以使用动态规划来寻找最长单词。具体步骤如下:

  • 定义一个dp数组,其中dp[i]表示长度为i的字符串s的所有子序列中,最长单词的长度。
  • 对于每个单词w,计算它在s中的最长子序列长度。如果w是s的子序列,则dp[w.length] = max(dp[w.length], w.length)。
  • 遍历dp数组,找到最大的值,它就是我们所要找的最长单词的长度。

3. 简化复杂度:贪心算法的精髓

在上述动态规划的基础上,我们还可以使用贪心算法来进一步简化问题的复杂度。具体步骤如下:

  • 从字典中选出最长的单词w。
  • 检查w是否是s的子序列。如果不是,则继续从字典中选出下一个最长的单词。
  • 重复步骤2,直到找到一个w,它既是s的子序列,又是字典中最长的单词。

4. 赏析代码:简洁高效的解法

def findLongestWord(s, d):
  # 排序字典
  d.sort(key=len, reverse=True)

  # 遍历字典
  for word in d:
    # 检查word是否是s的子序列
    if is_subsequence(word, s):
      # 返回最长单词
      return word

# 检查word是否是s的子序列
def is_subsequence(word, s):
  i = 0
  j = 0
  while i < len(word) and j < len(s):
    if word[i] == s[j]:
      i += 1
    j += 1
  return i == len(word)

5. 扩展阅读:多样解题思路的启发

除了上述方法外,还有多种解题思路可以解决这道题。例如,我们可以使用回溯法来枚举所有的匹配方案,或者使用二分查找来快速找到最长的匹配单词。这些不同的解题思路体现了算法的多样性,也启发我们在面对问题时,要敢于尝试不同的方法,才能找到最优解。