LeetCode: 524. 通过删除字母匹配到字典里最长单词

601 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第27天,点击查看活动详情

524. 通过删除字母匹配到字典里最长单词

来源:力扣(LeetCode) 链接: leetcode-cn.com/problems/lo…

给你一个字符串 s 和一个字符串数组 dictionary 作为字典,找出并返回字典中最长的字符串,该字符串可以通过删除 s 中的某些字符得到。

如果答案不止一个,返回长度最长且字典序最小的字符串。如果答案不存在,则返回空字符串。

示例 1:

输入:s = "abpcplea", dictionary = ["ale","apple","monkey","plea"] , 输出:"apple"

示例 2:

输入:s = "abpcplea", dictionary = ["a","b","c"], 输出:"a"

提示:

  • 1 <= s.length <= 1000
  • 1 <= dictionary.length <= 1000
  • 1 <= dictionary[i].length <= 1000
  • s 和 dictionary[i] 仅由小写英文字母组成

解法

乍看这道题真的觉得很难,又是删除字符串,又是最长的单词。遇事不决总想用DP解决。 原来思路还是比较简单的,有点想复杂了。 注意题目要求

返回 dictionary 中长度最长,且字典序最小的子串 可以删除 s 的部分字符 暴力地去解,其实就是s中每个字符和 dictionary 中每个 word 进行比较,记录最长的那一个,且字典序是最小的。

比较的方法无非是两个指针,分别指向 s 和 dictionary 中的 word,挨个比较下去。一旦 word 的指针长度跟 word 本身长度一致,就说明 s 删除一些子串可以变成 word。

中间的一些优化:

针对 dictionary 进行排序,让 word 长度比较长的排在前面,长度相等的情况下,让字典序小的排在前面 然后再拿 s 去跟排序之后的 dictionary 进行比较,一旦发现一个符合条件的就可以返回结果了,后续的都不需要比对了,因为排在前面的是更长且字典序更小的答案

  • python
class Solution:
    def findLongestWord(self, s: str, dictionary: List[str]) -> str:
        # sorted 中 key 是升序排序的,如果想要让 word 长度比较长的排在前面,可以取反 -len(x)
        sorted_dictionary = sorted(dictionary, key = lambda x: [-len(x), x])

        for w in sorted_dictionary:
            # 两个指针,分别指向 s 和 w
            p = 0
            q = 0
            while q < len(s):
                if s[q] == w[p]:
                    p += 1
                
                if p == len(w):
                    return w 

                q += 1
        return ""

复杂度分析

  • 时间复杂度:O(d×m×logd+d×(m+n))O(d×m×logd+d×(m+n)),其中 d 表示 dictionary 的长度,m 表示 s 的长度,n 表示 dictionary 中字符串的平均长度。需 O(d×m×logd) 的时间来排序 dictionary;在最坏的情况下,我们需要O(d×(m+n)) 来找到第一个符合条件的字符串。

  • 空间复杂度:O(d×m)O(d×m),为排序的开销。