2015-10-25 6 views
17

私はいくつかの同様の解決法をデバッグしていますが、Trie Treeを部分一致のプレフィックスに改善できるかどうか疑問です(Trieクラスの検索メソッドでは、現在の検索方法は完全な単語そうでない場合)、パフォーマンスを向上させることができます。私はそのアイデアには自信がないので、早期に助言を求める。単語検索のTrieツリーマッチ性能

私は同様の解決策を投稿しています。ありがとう。


2Dボードと辞書からの単語のリストが与えられた場合、ボード内のすべての単語を探します。

各単語は、連続した隣接セルの文字から構成する必要があります。「隣接セル」は、水平または垂直に隣接するセルです。同じ文字セルを単語に複数回使用することはできません。例えば

、 考えると言葉= ["oath","pea","eat","rain"]とボード=

[ 
    ['o','a','a','n'], 
    ['e','t','a','e'], 
    ['i','h','k','r'], 
    ['i','f','l','v'] 
] 

戻る[ "食べる"、 "誓い"]

class TrieNode(): 
    def __init__(self): 
     self.children = collections.defaultdict(TrieNode) 
     self.isWord = False 

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

    def insert(self, word): 
     node = self.root 
     for w in word: 
      node = node.children[w] 
     node.isWord = True 

    def search(self, word): 
     node = self.root 
     for w in word: 
      node = node.children.get(w) 
      if not node: 
       return False 
     return node.isWord 

class Solution(object): 
    def findWords(self, board, words): 
     res = [] 
     trie = Trie() 
     node = trie.root 
     for w in words: 
      trie.insert(w) 
     for i in xrange(len(board)): 
      for j in xrange(len(board[0])): 
       self.dfs(board, node, i, j, "", res) 
     return res 

    def dfs(self, board, node, i, j, path, res): 
     if node.isWord: 
      res.append(path) 
      node.isWord = False 
     if i < 0 or i >= len(board) or j < 0 or j >= len(board[0]): 
      return 
     tmp = board[i][j] 
     node = node.children.get(tmp) 
     if not node: 
      return 
     board[i][j] = "#" 
     self.dfs(board, node, i+1, j, path+tmp, res) 
     self.dfs(board, node, i-1, j, path+tmp, res) 
     self.dfs(board, node, i, j-1, path+tmp, res) 
     self.dfs(board, node, i, j+1, path+tmp, res) 
     board[i][j] = tmp 
+0

誰かが私の質問のパフォーマンスとコメントを改善するための良い考えを持っている場合、それは素晴らしいことがあります。ありがとう。 :) –

+2

Leetcodeからこのようなおなじみの質問:) – stanleyli

答えて

8

私は中Trie一部から間違った何も表示されません。あなたのコード。

しかし、トライのオリジナルのデザインは、不一致を検出したときにすでに早期復帰していると思います。

実際には、私は通常、問題を過度に複雑にすることを避けるために、defaultDict + TrieNodeではなく、通常はdictをトライとして使用します。特定のノードが有効な単語の場合は、"#"キーを設定するだけです。そして、挿入の間に、ちょうどnode[w] = {}をしてください。

これを行うと、ノードに「間違った」キーがまったくないので、コードを大幅に簡素化でき、早期返却が簡単になります!

たとえば、'ab'のみを含む単純なトライは、{'a': {'b': {'#': {}}}のようになります。したがって'cd'を検索すると、最も外側のdictにキー'c'が存在しなくなるとすぐにfalseを返すことができます。この実装はあなたのものと似ていますが、理解しやすいと思います。

+0

ありがとうstanleyliは、辞書ベースのソリューションに同意し、私たちはここでトリーの木を話しましょう。あなたのコメントのために、 "私はそれが"間違った経路から早く戻って "最適化"だとは思わない、なぜあなたは早期返却Falseのための解決策がないと思いますか?接頭辞が一致しない場合は、辞書一致の単語を決定しないというリターンが必要ですか? :) –

+0

ありがとうstanleyli、私の質問は、伝統的なツリーツリー、True(私のサンプルではisWord == Trueである単語の完全一致)を返すか、一致しないFalseを返します。部分一致の場合は、戻り値の型とロジックをどのように構成するべきだと思いますか?完全一致、部分一致または不一致の3種類を返す必要があると思いますか?ありがとう。 –

+1

申し訳ありませんあなたのコメントに「部分一致」が意味するものが混乱しています。私はあなたの答えが私の答えの一例だと思った。たぶんあなたはもっと説明するための例を挙げることができますか? – stanleyli