2【leetcode】字典树Trie 208、212

208. 实现 Trie (前缀树)
2【leetcode】字典树Trie 208、212

class Trie:
    def __init__(self):
        """
        Initialize your data structure here.
        """
        self.root = {}
        self.end_of_word = '#'

    def insert(self, word: str) -> None:
        """
        Inserts a word into the trie.
        """
        node = self.root 
        for char in word:
            # Python 如果字典中包含有给定键,则返回该键对应的值,否则返回为该键设置的值。
            node = node.setdefault(char, {})
        node[self.end_of_word] = self.end_of_word

    def search(self, word: str) -> bool:
        """
        Returns if the word is in the trie.
        """
        node = self.root 
        for char in word:
            if char not in node:
                return False 
            node = node[char]
        return self.end_of_word in node 

    def startsWith(self, prefix: str) -> bool:
        """
        Returns if there is any word in the trie that starts with the given prefix.
        """
        node = self.root 
        for char in prefix:
            if char not in node:
                return False 
            node = node[char]
        return True 

212. 单词搜索 II
2【leetcode】字典树Trie 208、212

2【leetcode】字典树Trie 208、212
这里的DFS是典型的递归问题,然后也是典型的 “四连通的写法”
2【leetcode】字典树Trie 208、212
2【leetcode】字典树Trie 208、212
2【leetcode】字典树Trie 208、212
2【leetcode】字典树Trie 208、212
因为是这里改变了 board 的状态,所以需要这里再次恢复一下这个状态

# 这里在处理 dfs 的问题的时候,采用了剪枝的方法,效果提升了很多
from collections import defaultdict as dt
class Solution:
    def findWords(self, board: List[List[str]], words: List[str]) -> List[str]:
        # 初始化 行,列
        m,n = len(board),len(board[0])
        # 创建 trie树,根据官方的骚方法
        Tree = lambda: dt(Tree)
        tree = Tree()
        for w in words: 
            reduce(dict.__getitem__,w+"#",tree)  # reduce 返回函数计算结果。
        # 初始化返回的list和方向
        ret = []
        directions = [[0,1],[0,-1],[1,0],[-1,0]]
        # 深度搜索
        def dfs(used,x,y,dic,now):
            if "#" in dic: # 如果dic是末尾字符,即包含"#"字符
                ret.append(now) # 结算
                del dic["#"] # "某字符":{"#":{}} 中的key="#" 没了,"某字符" 的字典也空了  --> 这里是为了剪枝去处理  
                
            used.add((x,y)) # 记录已访问过 board上的位置,避免这一次重复访问
            for direct in directions:
                # 四个方向 
                new_x = x + direct[0]
                new_y = y + direct[1]
                # 方向满足条件
                if 0 <= new_x < m and 0 <= new_y < n and (new_x,new_y) not in used:
                    # 检查这个新value是否在dic中
                    next_val = board[new_x][new_y]
                    if next_val in dic:
                        # 那么保存这个value,然后进入到对应这个value的字典
                        dfs(used,new_x,new_y,dic[next_val],now+next_val)
                        # 妙处,如果它里面没东西了,例如"#":{}已经被删除了。
                        # 那么它也没作用了
                        if not dic[next_val]: del dic[next_val]
            # 这一趟结束了,now已经存入ret,可以清除这个(x,y)
            used.remove((x,y))

        # 从每个节点开始
        for i in range(m):
            for j in range(n):
                curr_val = board[i][j]
                if curr_val in tree:
                    dfs(set(),i,j,tree[curr_val],curr_val)
                    if not tree[curr_val]: 
                        del tree[curr_val]

        return ret

上一篇:LeetCode 第 212 场周赛


下一篇:Api接口:在线查询手机入网时长入口