LeetCode 1268. Search Suggestions System - 前缀树(Trie Tree or Prefix Tree)系列题9

这篇博客介绍如何利用前缀树(Trie Tree)解决LeetCode上的1268题,即在输入字符串每个字符后提供最多三个匹配的产品名。博主展示了如何构建和遍历Trie树来找到与输入前缀匹配的最小字典序的三个产品名,并提及了二分查找法作为更优解。

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

Given an array of strings products and a string searchWord. We want to design a system that suggests at most three product names from products after each character of searchWord is typed. Suggested products should have common prefix with the searchWord. If there are more than three products with a common prefix return the three lexicographically minimums products.

Return list of lists of the suggested products after each character of searchWord is typed. 

Example 1:

Input: products = ["mobile","mouse","moneypot","monitor","mousepad"], searchWord = "mouse"
Output: [
["mobile","moneypot","monitor"],
["mobile","moneypot","monitor"],
["mouse","mousepad"],
["mouse","mousepad"],
["mouse","mousepad"]
]
Explanation: products sorted lexicographically = ["mobile","moneypot","monitor","mouse","mousepad"]
After typing m and mo all products match and we show user ["mobile","moneypot","monitor"]
After typing mou, mous and mouse the system suggests ["mouse","mousepad"]

Example 2:

Input: products = ["havana"], searchWord = "havana"
Output: [["havana"],["havana"],["havana"],["havana"],["havana"],["havana"]]

Example 3:

Input: products = ["bags","baggage","banner","box","cloths"], searchWord = "bags"
Output: [["baggage","bags","banner"],["baggage","bags","banner"],["baggage","bags"],["bags"]]

Example 4:

Input: products = ["havana"], searchWord = "tatiana"
Output: [[],[],[],[],[],[],[]]

Constraints:

  • 1 <= products.length <= 1000
  • There are no repeated elements in products.
  • 1 <= Σ products[i].length <= 2 * 10^4
  • All characters of products[i] are lower-case English letters.
  • 1 <= searchWord.length <= 1000
  • All characters of searchWord are lower-case English letters.

看到这样的题目很自然地想到了前缀树(Trie)。还是以LeetCode 208. Implement Trie (Prefix Tree) 为基础。前缀树Trie数据结构定义和单词插入都一样。区别还是查找条件,对于一个单词依次输入一个字母,每次输入一个字母形成该单词的前缀字符串,要求返回前缀树里与该前缀相匹配的3个单词。

从头开始扫描输入单词,每增加一个字母就形成一个新的前缀,前缀的每个字母都对应树里一个节点(如果没有匹配节点表示从该字母开始以后都没有匹配的节点,即每次答案都是空列表即0个相匹配单词),从前缀字符串最后一个字母对应的节点开始搜索整棵字母,找到3个单词(根据前缀树特点,最先找到的三个单词就为字母顺序排序最小的三个单词),然后把找到的3个(可能不够三个或为空)单词列表更新进结果列表。

class TrieNode:
    def __init__(self):
        self.end = False
        self.children = [None] * 26
        
class Solution:
    def suggestedProducts(self, products: List[str], searchWord: str) -> List[List[str]]:
        root = TrieNode()
        
        for word in products:
            node = root
            for c in word:
                idx = ord(c) - ord('a')
                if not node.children[idx]:
                    node.children[idx] = TrieNode()
                node = node.children[idx]
            node.end = True
            
        res = []
        node = root
        word = ''
        for c in searchWord:
            ans = []
            i = ord(c) - ord('a')
            if not node or not node.children[i]:
                node = None
                res.append(ans)
                continue
            node = node.children[i]
            word += c
            self.search(node, word, ans)
            res.append(ans)
        
        return res
                
        
    
    def search(self, root, word, ans):
        if len(ans) == 3:
            return
        
        if root.end:
            ans.append(word)
        
        for i in range(26):
            if not root.children[i]:
                continue
            tmp = word + chr(ord('a') + i)
            self.search(root.children[i], tmp, ans)

注:本文是为了熟练掌握前缀树,而前缀并非本题的最优解法。网上有大神用二分法查找来解答这题非常简洁和高效,大家可以搜索参考。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值