leetcode刷题笔记-trie

本文详细记录了使用Trie数据结构解决LeetCode中一系列问题的过程,包括字符串只相差一个字符的问题、二维网格中的单词搜索、查找字典中最长单词、设计自动补全系统以及实现前缀树等经典题目。通过这些题目,深入理解Trie在实际问题中的应用。

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

1554. Strings Differ by One Character

class Trie():
    def __init__(self):
        self.children = collections.defaultdict(Trie)
        self.isWord = False

    def insert(self, word):
        node = self
        for c in word:
            node = node.children[c]
        node.isWord = True

    def search(self, word, idx, miss_count):
        for c, child in self.children.items():  # 每条路径都要去查找
            is_diff = c != word[idx]  # 不用担心idx溢出,因为same length
            if miss_count + is_diff <= 1 and child.search(word, idx+1, miss_count + is_diff):
                return True
            
        return self.isWord and miss_count == 1


class Solution:
    def differByOne(self, dict: List[str]) -> bool:
        trie = Trie()

        for w in dict:
            trie.insert(w)
        
        for w in dict: # N
            if trie.search(w, 0, 0): # m*n  m is the 字母长度, 每条路径都要遍历
                return True
        return False

 

 212. Word Search II

class TrieNode():
    def __init__(self):
        self.children = collections.defaultdict(TrieNode)
        self.isWord = False
    
class Trie():
    def __init__(self):
        self.root = TrieNode()
    
    def insert(self, word):
        node = self.root
        for w in word:
            node = node.children[w]
        node.isWord = True
    
    def search(self, word):
        node = self.root
        for w in word:
            node = node.children.get(w)
            if not node:
                return False
        return node.isWord
    
class Solution(object):
    def findWords(self, board, words):
        res = []
        trie = Trie()
        node = trie.root
        for w in words:
            trie.insert(w)
        for i in xrange(len(board)):
            for j in xrange(len(board[0])):
                self.dfs(board, node, i, j, "", res)
        return res
    
    def dfs(self, board, node, i, j, path, res):
        if node.isWord:
            res.append(path)
            node.isWord = False
        if i < 0 or i >= len(board) or j < 0 or j >= len(board[0]):
            return 
        tmp = board[i][j]
        node = node.children.get(tmp)
        if not node:
            return 
        board[i][j] = "#"
        self.dfs(board, node, i+1, j, path+tmp, res)
        self.dfs(board, node, i-1, j, path+tmp, res)
        self.dfs(board, node, i, j-1, path+tmp, res)
        self.dfs(board, node, i, j+1, path+tmp, res)
        board[i][j] = tmp

720. Longest Word in Dictionary

class TrieNode:
    def __init__(self):
        self.childern = collections.defaultdict(TrieNode)
        self.word = ""
        
class Trie:
    def __init__(self):
        self.root = TrieNode()
        
    def insert(self, word):
        node = self.root
        for c in word:
            node = node.childern[c]
        node.word = word
        
   
class Solution:
    def longestWord(self, words: List[str]) -> str:
        trie = Trie()
        for word in words:
            trie.insert(word)
        
        # BFS
        
        q = [trie.root]
        re = ""
        while q:
            node = q.pop(0)
            
            for n in node.childern.values():
                if n.word:
                    q.append(n)
                    
                    if len(n.word) > len(re) or n.word < re:
                        re = n.word
        return re

642. Design Search Autocomplete System

class TrieNode():
    def __init__(self):
        self.children = collections.defaultdict(TrieNode)
        self.isEnd = False
        self.rank = 0
        self.data = ''
        
class AutocompleteSystem(object):

    def __init__(self, sentences, times):
        self.root = TrieNode()
        for i, sentence in enumerate(sentences):
            self.addRecord(sentence, times[i])
        self.keyWords = ''
    
    def addRecord(self, sentence, time):
        node = self.root
        for c in sentence:
            node = node.children[c]
        node.isEnd = True
        node.rank -= time
        node.data = sentence

    def input(self, c):
        res = []
        if c != '#':
            self.keyWords += c
            res = self.search(self.keyWords)
        else:
            self.addRecord(self.keyWords, 1)
            self.keyWords = ''
        return res
    
    def search(self, sentence):
        node = self.root
        for c in sentence:
            node = node.children.get(c)
            if not node:
                return []
        res = self.dfs(node)
        return [data for rank, data in sorted(res)[:3]]
        
    def dfs(self, node): # 找到该节点下的所有句子
        res = []
        if node:
            if node.isEnd:
                res.append([node.rank, node.data])
            for child in node.children.values():
                res.extend(self.dfs(child))
        return res
    

208. Implement Trie (Prefix Tree)

class TrieNode():
    def __init__(self):
        self.children = collections.defaultdict(TrieNode)
        self.isWord = False
        

class Trie(object):

    def __init__(self):
        self.root = TrieNode()

    def insert(self, word):
        node = self.root
        for c in word:
            node = node.children[c]
        node.isWord = True
        

    def search(self, word):
        node = self.root
        for c in word:
            node = node.children.get(c)  # 不用用 node.children[c] 否则永远都不会是None
            if not node:
                return False
        return node.isWord
    
    def startsWith(self, prefix):
        node = self.root
        for c in prefix:
            node = node.children.get(c)
            if not node:
                return False
     
        return True

211. Add and Search Word - Data structure design

class TrieNode():
    def __init__(self):
        self.children = collections.defaultdict(TrieNode)
        self.isWord = False

        
class WordDictionary(object):

    def __init__(self):
        """ 
        TrieNode:
        根节点不包含字符,除根节点外每一个节点都只包含一个字符。
        从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串。
        每个节点的所有子节点包含的字符都不相同。
        """
        self.root = TrieNode()  

    def addWord(self, word):
        """
        Adds a word into the data structure.
        :type word: str
        :rtype: void
        """
        node = self.root
        for c in word:
            node = node.children[c]
        node.isWord = True
        
    def search(self, word):
        """
        Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter.
        :type word: str
        :rtype: bool
        """
        node = self.root
        self.res = False
        self.dfs(node, word)
        return self.res
    
    def dfs(self, node, word):
        if not word:
            if node.isWord:
                self.res = True
            return
        
        if word[0] == '.':
            for n in node.children.values():
                self.dfs(n, word[1:])
        else:
            n = node.children.get(word[0])  # 不能写 node.children[word[0]] 不然会返回默认类型
            if not n:
                return
            self.dfs(n, word[1:])
        

588. Design In-Memory File System

Trie = lambda: collections.defaultdict(Trie)
class FileSystem(object):

    def __init__(self):
        self.fs = Trie()
        self.fileinfo = collections.defaultdict(str)

    def ls(self, path):
        if path in self.fileinfo:
            return path.split('/')[-1:]
        
        cur = self.fs
        for token in path.split('/'):
            if token in cur:
                cur = cur[token]
            elif token:
                return []
        return sorted(cur.keys())

    def mkdir(self, path):
        cur = self.fs
        for token in path.split('/'):
            if token:
                cur = cur[token]

    def addContentToFile(self, filePath, content):
        self.mkdir(filePath)
        self.fileinfo[filePath] += content
        
        
    def readContentFromFile(self, filePath):
        return self.fileinfo[filePath]

212. Word Search II

class Solution(object):
    def findWords(self, board, words):
        """
        :type board: List[List[str]]
        :type words: List[str]
        :rtype: List[str]
        """
        trie = {}
        for w in words:
            t = trie
            for c in w:
                if c not in t:
                    t[c] = {}
                t = t[c]
            t['#'] = '#'
        
        self.res = set()
        self.used = [[0] * len(board[0]) for _ in xrange(len(board))]
        
        for i in xrange(len(board)):
            for j in xrange(len(board[0])):
                self.find(i, j, board, trie, "")
        return list(self.res)
    
    
    def find(self, i, j, board, trie, pre):
        if '#' in trie:
            self.res.add(pre)
        
        if i < 0 or i >= len(board) or j < 0 or j >= len(board[0]):
            return
        
        if not self.used[i][j] and board[i][j] in trie:
            self.used[i][j] = True
            for x, y in ((-1, 0), (1, 0), (0, 1), (0, -1)):
                self.find(i+x, j+y, board, trie[board[i][j]], pre+board[i][j])
            self.used[i][j] = False
            

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值