每日一道Leetcode -面试题 17.13. 恢复空格 【动态规划|字典树】

该博客介绍了如何使用字典树(Trie)数据结构优化动态规划算法,以解决从给定的单词字典中找到最短未匹配单词数量的问题。具体实现包括字典树的构建、插入单词以及搜索功能,以及动态规划的解决方案。通过这种方法,可以高效地处理句子中单词的匹配情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述

class TrieNode:
    def __init__(self):
        self.isWord = False
        self.children = [None for _ in range(26)]
class Trie:
    def __init__(self):
        self.root = TrieNode()
    # 将dic中的单词倒序插入字典树
    def insert(self,word):
        cur = self.root
        for i in range(len(word)-1,-1,-1):
            c = ord(word[i]) - ord('a')
            if cur.children[c] == None:
                cur.children[c] = TrieNode()
            cur = cur.children[c]
        cur.isWord = True
    # 找到 sentence 中以 endPos 为结尾的单词,返回这些单词的开头下标。
    def search(self,word,endPos):
        indices = []
        cur = self.root
        for i in range(endPos,-1,-1):
            c = ord(word[i]) - ord('a')
            if cur.children[c]==None:
                break
            cur = cur.children[c]
            if cur.isWord:
                indices.append(i)
        return indices

class Solution:
    def respace(self, dictionary: List[str], sentence: str) -> int:
        """
        # 使用动态规划
        # dp数组表示以当前元素结尾的最小未匹配数
        n = len(sentence)
        dp = [0]*(n+1)
        for i in range(1,n+1):
            # 未匹配的情况
            dp[i] = dp[i-1]+1
            # 查找当前字符之前以idx开始的字符串是否在字典中,如果在,就更行dp数组
            for idx in range(0,i):
                if sentence[idx:i] in dictionary:
                    dp[i] = min(dp[i],dp[idx])
        return dp[n]
        """

        # 法二,使用字典树,字典树是逆序构造
        trie = Trie()
        for word in dictionary:
            trie.insert(word)
        n = len(sentence)
        dp = [0]*(n+1)
        for i in range(1,n+1):
            dp[i] = dp[i-1]+1
            for idx in trie.search(sentence,i-1):
                dp[i] = min(dp[i],dp[idx])
        return dp[n]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值