(Leetcode) 单词搜索 II - Python实现

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

说明 :
你可以假设所有输入都由小写字母 a-z 组成。

提示 :
你需要优化回溯算法以通过更大数据量的测试。你能否早点停止回溯?
如果当前单词不存在于所有单词的前缀中,则可以立即停止回溯。什么样的数据结构可以有效地执行这样的操作?散列表是否可行?为什么? 前缀树如何?如果你想学习如何实现一个基本的前缀树,请先查看这个问题: 实现Trie(前缀树)。

-------------------------------------------------------------------------

思路:利用前面写过的前缀树算法,在加上深度优先遍历。

 

解法1:前缀树 + dfs(深度优先搜索)

class Trie(object):

    def __init__(self):
        self.root = {}

    def insert(self, word):
        """
        Inserts a word into the trie.
        :type word: str
        :rtype: void
        """
        curNode = self.root
        for i in word:
            if i not in curNode:
                curNode[i] = {}
            curNode = curNode[i]
        curNode["#"] = True

class Solution(object):
    def findWords(self, board, words):
        """
        :type board: List[List[str]]
        :type words: List[str]
        :rtype: List[str]
        """
        row = len(board)
        colum = len(board[0])
        res = []

        def find(x, y, word, TrieNode):
            if x >= 0 and x < row and y >= 0 and y < colum and board[x][y] in TrieNode:
                TrieNode = TrieNode[board[x][y]]
                word += board[x][y]
                if TrieNode.get("#", 9) == True:
                    res.append(word)
                t = board[x][y]
                board[x][y] = 3
                find(x + 1, y, word, TrieNode)
                find(x - 1, y, word, TrieNode)
                find(x, y + 1, word, TrieNode)
                find(x, y - 1, word, TrieNode)
                board[x][y] = t

        root = Trie()
        tmp = set()
        for i in words:
            root.insert(i)
            tmp.add(i[0])
        for i in range(row):
            for j in range(colum):
                if board[i][j] in tmp:
                    find(i, j, "", root.root)

        return list(set(res))
    

解法2:解法1的变体

class Trie(object):
    def __init__(self):
        """
        Initialize your data structure here.
        """
        self.root = {}
 
    def insert(self, word):
        """
        Inserts a word into the trie.
        :type word: str
        :rtype: None
        """
        node = self.root
        for char in word:
            node = node.setdefault(char, {})
            
        node["end"] = True
 
    def search(self, word):
        """
        Returns if the word is in the trie.
        :type word: str
        :rtype: bool
        """
        node = self.root
        for char in word:
            if char not in node:
                return False
            node = node[char]
        return "end" in node
 
    def startsWith(self, prefix):
        """
        Returns if there is any word in the trie that starts with the given prefix.
        :type prefix: str
        :rtype: bool
        """
        node = self.root
        for char in prefix:
            if char not in node:
                return False
            node = node[char]
        return True
 
class Solution(object):
    def findWords(self, board, words):
        """
        :type board: List[List[str]]
        :type words: List[str]
        :rtype: List[str]
        """
        if not board or not board[0]:
            return []
        m, n = len(board), len(board[0])
        dx = [1, -1, 0, 0]
        dy = [0, 0, 1, -1]
        tree = Trie()
        for word in words:
            tree.insert(word)
        words = set(words)
        
        res = set()
        def dfs(x0, y0, node, tmpword):
            visited.add((x0, y0))
            for k in range(4):
                x = x0 + dx[k]
                y = y0 + dy[k]
                
                if 0 <= x < m and 0 <= y < n and board[x][y] in node and (x, y) not in visited:
                    visited.add((x, y))
                    dfs(x, y, node[board[x][y]], tmpword + board[x][y])
                    visited.remove((x,y))
                    
            if tmpword in words: #找到一个单词了
                res.add(tmpword) #用集合避免重复
                    
        for i in range(m):
            for j in range(n):
                if board[i][j] in tree.root:
                    visited = set((i,j))
                    dfs(i, j, tree.root[board[i][j]], board[i][j])
        return list(res)

 

参考:

https://www.jianshu.com/p/98ea4744a71d

https://blog.csdn.net/ywd19950901/article/details/82798036

https://blog.csdn.net/weixin_41303016/article/details/88393706

https://blog.csdn.net/qq_32424059/article/details/97268022

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值