[Leetcode] 212. Word Search @python

题目

Given a 2D board and a list of words from the dictionary, find all words in the board.

Each word must be constructed from letters of sequentially adjacent cell, where “adjacent” cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once in a word.

For example,
Given words = [“oath”,”pea”,”eat”,”rain”] and board =

[
[‘o’,’a’,’a’,’n’],
[‘e’,’t’,’a’,’e’],
[‘i’,’h’,’k’,’r’],
[‘i’,’f’,’l’,’v’]
]
Return [“eat”,”oath”].
Note:
You may assume that all inputs are consist of lowercase letters a-z.

题目要求

给定一个二维的字母表,其中包含a-z的元素,可重复,一个单词列表。判断单词列表中有哪些单词在字母表中可以找到,找到的依据是字母与相邻的字母可以组成该单词,相邻指上下左右,且每个位置的字母只能用一次。

解题思路

此题采用了字典树的结构来存储单词表,每从字母表中找到一个单词,从字典树中将该单词删除。采用深度优先搜索的方式来遍历字母表。并用visited数组存储字母表中的元素是否被访问过。

代码

class Solution(object):
    def findWords(self, board, words):
        """
        :type board: List[List[str]]
        :type words: List[str]
        :rtype: List[str]
        """


        if len(board) == 0:
            return []
        row,col = len(board),len(board[0])
        visited = [[False for _ in range(col)] for _ in range(row)]
        trie = Trie()
        for word in words:
            trie.insert(word)
        dz = zip([0,0,1,-1],[-1,1,0,0])
        res = []
        def dfs(word,node,x,y):
            child = node.childs.get(board[x][y])
            if child == None:
                return
            node = child
            visited[x][y] = True

            for dx,dy in dz:
                nx,ny = x + dx,y + dy
                if nx >= 0 and nx < row and ny >= 0 and ny < col and not visited[nx][ny]:
                    dfs(word + board[nx][ny],node,nx,ny)    
            visited[x][y] = False
            if node.isWord:
                res.append(word)
                trie.delete(word)
        for x in range(row):
            for y in range(col):
                dfs(board[x][y],trie.root,x,y)
        return res



class TrieNode(object):
    def __init__(self):
        self.childs = {}
        self.isWord = False

class Trie(object):

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

    def insert(self,word):
        node = self.root
        for letter in word:
            child = node.childs.get(letter)
            if child == None:
                child = TrieNode()
                node.childs[letter] = child
            node = child
        node.isWord = True

    def delete(self,word):
        node = self.root
        queue = []
        for letter in word:
            queue.append((letter,node))
            child = node.childs.get(letter)
            if not child:
                return False
            node = child
        if not node.isWord:
            return False
        if node.childs:
            node.isWord = False
        else:
            for letter,node in reversed(queue):
                del node.childs[letter]
                if node.childs or node.isWord:
                    break
        return True



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值