dfs solve the (implicit) graph search problem

132. Word Search II

Chinese
English

Given a matrix and a dictionary of lowercase letters. Find all the words also appear in the dictionary and matrix. A word can begin anywhere in the matrix, you can be left / right / upper / lower four adjacent moving direction. A letter in a word can only be used once. And there is no repetition of words in the dictionary

Sample

Example 1:

输入:["doaf","agai","dcan"],["dog","dad","dgdg","can","again"]
输出:["again","can","dad","dog"]
解释:
  d o a f
  a g a i
  d c a n
矩阵中查找,返回 ["again","can","dad","dog"]。

Sample 2:

输入:["a"],["b"]
输出:[]
解释:
 a
矩阵中查找,返回 []。

challenge

Use trie to implement your algorithm

 

DIRECTIONS = [(0, -1), (0, 1), (-1, 0), (1, 0)]

class Solution:
    """
    @param board: A list of lists of character
    @param words: A list of string
    @return: A list of string
    """
    def wordSearchII(self, board, words):
        if board is None or len(board) == 0:
            return []
        
        word_set = set(words)
        prefix_set = set()
        for word in words:
            for i in range(len(word)):
                prefix_set.add(word[:i + 1])
        
        result = set()
        for i in range(len(board)):
            for j in range(len(board[0])):
                c = board[i][j]
                self.search(
                    board,
                    i,
                    j,
                    board[i][j],
                    word_set,
                    prefix_set,
                    set([(i, j)]),
                    result,
                )
                
        return list(result)
        
    def search(self, board, x, y, word, word_set, prefix_set, visited, result):
        if word not in prefix_set:
            return
        
        if word in word_set:
            result.add(word)
        
        for delta_x, delta_y in DIRECTIONS:
            x_ = x + delta_x
            y_ = y + delta_y
            
            if not self.inside(board, x_, y_):
                continue
            if (x_, y_) in visited:
                continue
            
            visited.add((x_, y_))
            self.search(
                board,
                x_,
                y_,
                word + board[x_][y_],
                word_set,
                prefix_set,
                visited,
                result,
            )
            visited.remove((x_, y_))
            
    def inside(self, board, x, y):
        return 0 <= x < len(board) and 0 <= y < len(board[0])

 Note the use of prefix hash map to pruning.

Solution trie use of:

= ThereDIRECTIONS [(0, -1), (0,. 1), (-1, 0), (. 1, 0)] 

class TrieNode: #define trie nodes 
    DEF the __init __ (Self): 
        self.children = {} 
        = False self.is_word 
        self.word = None 
        
        
class Trie: 
    DEF __init __ (Self): 
        self.root = TrieNode () 
        
    DEF the Add (Self, Word): # trie insert the word 
        the Node = self.root 
        for c in Word: 
            IF node.children not in c: 
                node.children [c] = TrieNode () # application at this node node 
            # = node.children continue to traverse the node [c] 
        node.is_word = True 
        node.word = # into Word word 
        
    def find (Self, Word):	 
        Node = self.root 
        for c in Word: 
            Node = node.children.get (C) 
            IF None Node IS: 
                return None 
                
        return Node 
        

class Solution: 
    "" " 
    @param Board: A Character List of Lists of 
    @param words: A List of String 
    @return : List of String A 
    "" " 
    DEF wordSearchII (Self, Board, words): 
        IF Board or IS None len (Board) == 0: 
            return [] 
            
        Trie Trie = () 
        for Word in words: # insert word 
            trie.add (Word) 

        the Result = the SET () 
        for i in the Range (len (Board)): # ergodic matrix alphabet, each letter as the first letter of the word to start the search
            for j in range(len(board[0])):
                c = board[i][j]
                self.search(
                    board,
                    i,
                    j,
                    trie.root.children.get(c),
                    set([(i, j)]),
                    result,
                )
                
        return list(result)
        
    def search(self, board, x, y, node, visited, result):			#在字典树上dfs查找
        if node is None:
            return
        
        if node.is_word:
            result.add(node.word)
        
        for delta_x, delta_y in DIRECTIONS:				#向四个方向查找
            x_ = x + delta_x
            y_ = y + delta_y
            
            if not self.inside(board, x_, y_):
                continue
            if (x_, y_) in visited:
                continue
            
            visited.add((x_, y_))
            self.search(
                board,
                x_,
                y_,
                node.children.get(board[x_][y_]),
                visited,
                result,
            )
            visited.remove((x_, y_))
            
    def inside(self, board, x, y):
        return 0 <= x < len(board) and 0 <= y < len(board[0])

 

Guess you like

Origin www.cnblogs.com/bonelee/p/11740956.html