Leetcodeソリューション173:バイナリ検索ツリーのイテレータ

 

 問題文 

二分探索木(BST)の反復子を実装します。あなたのイテレータは、BSTのルートノードで初期化されます。

通話は、  next() BSTの次の最小数を返します。

 

例:

BSTIterator反復子=新しいBSTIterator(ルート)。
iterator.next(); 3返す// 
)(iterator.nextを。// 7返す
iterator.hasNextは(); trueを返す// 
)(iterator.nextを。// 9戻る
iterator.hasNextは(); trueを返す// 
)(iterator.nextを。15返す// 
iterator.hasNextを(); trueを返す// 
)(iterator.nextを。20返す// 
iterator.hasNextを(); // falseを返します

 

注意:

  • next() 及び  hasNext() 平均O(1)時間で実行され、O(使用しなければならない時間)メモリ、  hは  木の高さを。
  • あなたはその仮定してもよい  next() ときBSTに少なくとも次の最小の数があるでしょう、つまり、呼び出しは常に有効になります  next() と呼ばれています。

問題のリンク

 

ビデオチュートリアル

あなたはここに詳細なビデオチュートリアルを見つけることができます

 

思考プロセス

 

アレイ法へのブルートフォース・ダンプ・ツリー

それは順序トラバーサルにBSTと非常によく似ています。思考のその電車からは、我々は簡単にブルートフォースソリューションを持つことができます:インオーダートラバースを行い、配列にその順序をダンプします。その後、我々は、配列へのポインタポイントを持つことができ、前方に私達は次の()メソッドを呼び出すたびにポインタを移動します。この強引な方法の時間計算量は、コンストラクタ段階でO(N)(Nは、ツリー内のノードの総数である)です。私たちはツリーを2回反復しても、それはO(N)、のhasNext()と次はまだだ()すべてのOになります(1)。私たちは、ツリー内のすべての要素を格納するために余分な配列を必要とするので、スペースの複雑さは、同様にO(N)です。

その配列を反復配列にツリーをダンプする強引な方法

画像のクレジット:https://leetcode.com/articles/binary-search-tree-iterator/

 

 

 

順トラバーサルではスタックを使用して  

 

hは木の高さ別名O(H)O(LGN)をO(N)からメモリを低減するために、代替的には、我々は再帰を実行している間に、次の()インラインを返すあります。我々はまだ再帰を使用して、順序トラバーサルを実行する場合トリッキーな部分は、再帰呼び出しにnext()メソッドをプラグインするためのない簡単な方法は存在しません。

 

私たちは常に、スタック内のツリーノードを持つことにより、再帰(プッシュ機能のスタック部)をシミュレートするために、スタックを使用することができます知っている、それは前任者と後継者を追跡することも簡単です。開始位置が左端のノードであるツリーの中で最小のノード、を指している必要があり、我々は左に行くと、我々はスタックに訪れたノードをプッシュし続けます。次の()が呼び出されるたびに、我々は、スタックの先頭を返し、ノードのいずれかの右の子がある場合はそうならば、私たちは、チェック、我々は多くても1つを左を打つまで、スタックにノードを押し続けます。hasNext()は単にスタック内のノードがまだあるかどうかをチェックされます。次の時間計算量は()も、我々はハイレベルで以来、一番左の子を見つけ保つためにwhileループを持っている(1)平均Oになり、各ノードは、まだ一度だけ訪れています。

 

Initial stage

Image credit: https://leetcode.com/articles/binary-search-tree-iterator/

 

Find the left most child

Image credit: https://leetcode.com/articles/binary-search-tree-iterator/

 

 

Solutions

 

In order traversal using stack

Note in next() method, we don't need to check if there is still element left in the stack. It is the caller's responsibility to check so. It is described in the Java's Iterator interface NoSuchElementException should be thrown.

 

 1 public class BinarySearchTreeIterator {
 2     private Stack<TreeNode> stack = null;
 3 
 4     public BinarySearchTreeIterator(TreeNode root) {
 5         this.stack = new Stack<TreeNode>();
 6 
 7         while (root != null) {
 8             this.stack.push(root);
 9             root = root.left;
10         }
11     }
12 
13     /** @return whether we have a next smallest number */
14     public boolean hasNext() {
15         return !this.stack.isEmpty();
16     }
17 
18     /** @return the next smallest number */
19     // essentially using a stack to implement in-order traversal
20     public int next() {
21         // caller should check using hasNext() else NoSuchElementException
22         TreeNode t = this.stack.pop();
23 
24         if (t.right != null) {
25             this.stack.push(t.right);
26 
27             TreeNode c = t.right.left;
28 
29             while (c != null) {
30                 this.stack.push(c);
31                 c = c.left;
32             }
33         }
34         return t.val;
35     }
36 
37 }

 

 

 

Time Complexity: next(), hasNext() O(1) on average even with the while loop, think each node is visited essentially only once

Space Complexity: O(lgN), extra stack is needed capped at tree height

 

References

おすすめ

転載: www.cnblogs.com/baozitraining/p/11403384.html
おすすめ