LC 212. 单词搜索2

原题链接

https://leetcode-cn.com/problems/word-search-ii/

原题描述

给定一个 m x n 二维字符网格 board 和一个单词(字符串)列表 words,找出所有同时在二维网格和字典中出现的单词。
单词必须按照字母顺序,通过 相邻的单元格 内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母在一个单词中不允许被重复使用。

范例1

输入:board = [["o","a","a","n"],["e","t","a","e"],["i","h","k","r"],["i","f","l","v"]], words = ["oath","pea","eat","rain"]
输出:["eat","oath"]

范例2

输入:board = [["a","b"],["c","d"]], words = ["abcb"]
输出:[]

解答

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)
        # 初始化返回的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
posted @ 2020-11-11 04:17  schaffen  阅读(154)  评论(0编辑  收藏  举报