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

题目描述

在这里插入图片描述

分析

最朴素的思想是通过枚举字典中的每个单词,判断其是否在s中出现过,然后选择长度最大且字典序最小的单词返回

代码一

def findLongestWord(self, s: str, dictionary: list[str]) -> str:
        res = ""
        for t in dictionary:
            i = j = 0
            while i < len(t) and j < len(s):
                if t[i] == s[j]:
                    i += 1
                j += 1
            if i == len(t):
                if len(t) > len(res) or (len(t) == len(res) and t < res):
                    res = t
        return res

分析代码一可以发现,需要枚举所有的单词才能确定结果,如果事先对字典中的单词按照长度降序排列,字典序升序排列,那么第一个出现在s中的单词就是最终的结果

代码二

 def findLongestWord(self, s: str, dictionary: list[str]) -> str:
        # 对字典按照长度降序,字典序升序排列,原地排序
        dictionary.sort(key=lambda x:(-len(x), x))
        for d in dictionary:
            i = j = 0
            while i < len(s) and j < len(d):
                if s[i] == d[j]:
                    j += 1
                i += 1
            if j == len(d):
                return d
        return ""

分析代码二可以发现,耗时操作主要用于寻找下一个匹配字符,如果能在o(1)时间内找到从当前为止开始的下一个匹配字符的为止,则可以大大降低检索的时间,假设 f [ i ] [ j ] f[i][j] f[i][j]表示s中从位置i开始字符j第一次出现的位置则有下面的状态转移方程:
在这里插入图片描述

代码三

def findLongestWord(self, s: str, dictionary) -> str:
        # 初始化dp矩阵,这种初始化存在问题,dp每个列表都指向相同的地址,修改其中一个会改变其他的列表元素
        # dp = [[-1] * 26] * len(s)
        dp = []
        for i in range(0, len(s)):
            dp.append([-1] * 26)
        # 从过后往前填充矩阵 ord是获取字符的ASCII码,chr是获取对应ASCII码的字符
        dp[len(s) - 1][ord(s[len(s) - 1]) - ord('a')] = len(s) - 1
        for i in range(len(s) - 2, -1, -1):
            for j in range(25, -1, -1):
                if s[i] == chr(j + ord('a')):
                    dp[i][j] = i
                else:
                    dp[i][j] = dp[i + 1][j]
        # 对字典进行排序
        dictionary.sort(key=lambda x:(-len(x), x))
        for d in dictionary:
            i = j = 0
            while i < len(d) and j < len(s):
                # 查找字符d[i]从为止j开始是否出现过
                if dp[j][ord(d[i]) - ord('a')] == -1:
                    break
                j = dp[j][ord(d[i]) - ord('a')] + 1
                i += 1
            if i == len(d):
                return d
        return ""
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值