1.最小深さのバイナリツリー
タイトル説明
問題解決のためのアイデア
各ノードバイナリツリーを再帰的にトラバース。
ノードがnullの場合(1)、0は、深さを返されます。
(2)ノードが空でない場合は、子供の深さ+1という小さな子供の左右を返します。
注:唯一つのノードが子を残した場合には(2)の問題が発生する可能性がある、権利子が、この時点で返さない深さの子をままにしておく必要があり、単に両者の最小値を返すと考えられるべきではありません。
1つの パブリック クラスソリューション{ 2 公共 int型のラン(ツリーノードのルート){ 3 であれば(ルート== NULL ) 4 戻り 0 ; 5 int型の右= 実行(root.right)。 6 INT左= ラン(root.left)。 7 リターン(左== 0 ||右== 0)?(左+右+ 1):Math.min(左、右)+1 。 8 } 9 }
2.二分木-後順トラバーサル
タイトル説明
バイナリツリーを考えると、リターン 後順の バイナリツリーを横断した後、そのノードの値のトラバーサル。
例えば:
バイナリツリー{1、#、2,3}が与えられると、
1 \ 2 / 3
[3,2,1]を返します。
注意: 再帰的な解決策は簡単です、あなたは繰り返しそれを行うだろうか?
問題解決のアイデア:
シーケンス後のトラバーサル順序は次のとおりです。左- >右- >ルートは、再帰的な方法はよく書きます。
1つの パブリック クラスソリューション{ 2 のArrayList <整数>リスト= 新規のArrayList <整数> (); 3 公共のArrayList <整数> postorderTraversal(ツリーノードのルート){ 4 もし(ルート== NULL ) 5 リターンリスト。 6 もし(root.left =!ヌル) 7 postorderTraversal(root.left)。 8 もし(root.right =!ヌル) 9 postorderTraversal(root.right)。 10 list.add(root.val)。 11 戻り値のリスト。 12 } 13 }
非再帰的な反復にスタックを使用する方法:
要保证根结点在左孩子和右孩子访问之后才能访问,因此对于任一结点P,先将其入栈。
(1)如果P不存在左孩子和右孩子,则可以直接访问它;
(2)或者P存在孩子,但是其孩子都已被访问过了,则同样可以直接访问该结点
(3)若非上述两种情况,则将P的右孩子和左孩子依次入栈,这样就保证了
注意:每次取栈顶元素的时候,左孩子在右孩子前面被访问,左孩子和右孩子都在根结点前面被访问。
1つの パブリック クラスソリューション{ 2 公共のArrayList <整数> postorderTraversal(ツリーノードのルート){ 3 のArrayList <整数>リスト= 新規のArrayList <整数> (); 4 もし(ルート== NULL ) 5 リターンリスト。 6 スタック<ツリーノード> S = 新しいスタック<ツリーノード> (); 7 ツリーノードpreNode = NULL ; 8 S.push(ルート)。 9 ながら(!S.isEmpty()){ 10 のTreeNode curNode =S.peek(); 11 であれば((curNode.left == NULL && curNode.right == NULL)|| 12 (preNode!= NULL &&(preNode == curNode.left || preNode == curNode.right))){ 13 list.add (curNode.val)。 14 S.pop()。 15 preNode = curNode。 16 } 17 他{ 18 であれば(curNode.right!= NULL ) 19 S.push(curNode.right)。 20 もし(curNode.left!= nullを) 21 S.push(curNode.left)。 22 } 23 } 24 リターンリスト。 25 } 26 }
3.バイナリ・ツリー・予約限定!トラバーサル
タイトル説明
バイナリツリーは、戻り与えられた 先行順 のITSノードの値のトラバーサル。非再帰をバイナリツリーを横断する前に
例えば:
バイナリツリー{1、#、2,3}が与えられると、
1 \ 2 / 3
[1,2,3]を返します。
注意: 再帰的な解決策は簡単です、あなたは繰り返しそれを行うだろうか?
問題解決のアイデア:
1つの パブリック クラスソリューション{ 2 公共のArrayList <整数> preorderTraversal(ツリーノードのルート){ 3 スタック<ツリーノード> S = 新しいスタック<ツリーノード> (); 4 のArrayList <整数>リスト= 新規のArrayList <整数> (); 5 もし(ルート== NULL ){ 6 戻りリスト。 7 } 8 S.push(ルート)。 9 ながら(!S.isEmpty()){ 10 のTreeNode TMP = S.pop()。 11 list.add(tmp.val)。 12 であれば(tmp.right!= NULL ) 13 S.push(tmp.right)。 14 もし(tmp.left =!ヌル) 15 S.push(tmp.left)。 16 } 17 リターンリスト。 18 } 19 }
4.サム・ルート・ツー・リーフ番号
タイトル説明
のみ0-9の数字を含むバイナリツリーが与えられると、各ルート・ツー・リーフパス番号を表すことができます。
例では、ルート・ツー・リーフpath1-> 2-> 3whichはnumber123を表しています。
すべてのルート・ツー・葉の数の合計を検索します。
例えば、
1 / \ 2 3
ルート・ツー・葉path1->はnumber12を2represents。
ルート・ツー・葉path1->はnumber13を3represents。
合計= 12 + 13 = 25を返します。
バイナリツリーのリーフノードにルートノードから各パスは数によって表され、これらの図を求めることができるしています。
問題解決のアイデア:
使用再帰を主に再帰的な条件と終了条件を考慮して、行うこと。再帰的な条件、即ち和が現在のノードに加え、現在の10倍し再帰次関数に渡され、左右のサブツリーの最終的な和が加算されます。終了条件は、ノードが葉である場合は、空のノードではなく、リーフノードにノードならば、我々は直接0に戻し、結果を追加することなく、結果の和を蓄積する必要があることである場合。それは本質的に前順。
1つの パブリック クラスソリューション{ 2 公共 INT sumNumbers(ツリーノードのルート){ 3 戻り数(ルート、0 ); 4 } 5 静的 INT数(ツリーノードのルート、int型の合計){ 6 場合(ルート== NULL ) 7 戻り 0 ; 8 もし(root.left == NULL && root.right == NULL ) 9 戻り和* 10 + root.val。 10 リターンカウント(root.left、合計* 10 + root.val)+カウント(root.right、合計* 10 + root.val)。 11 } 12 }
前記バイナリツリーの最大パス和
タイトル説明
バイナリツリーを考えると、最大パスの合計を見つけます。
パスが起動し、ツリー内の任意のノードで終了してもよいです。
たとえば:
バイナリツリーの下に考えると、
1 / \ 2 3
6を返します。
バイナリツリーと最大の一つのパス検索(繰り返さないでください、出発点ではなく、rootとして任意のノードを、交差していません)
問題解決のアイデア:
再帰的に各ノードと最大パスの左と右の部分木を検索、ルートノードから開始して、現在のノードは、値+左サブツリーと大きくを返します。
それぞれの可能な経路を横断するときことに注意してください、そして最大値は現在このパスに更新され、その後、更新さ未満です。
1 パブリック クラスソリューション{ 2 公共の int型の和= はInteger.MIN_VALUE。 3 公共 INT maxPathSum(ツリーノードのルート){ 4 もし(ルート== NULL ) 5 リターン 0 。 6 MAX(ルート)。 7 リターン合計。 8 } 9 公共の int型の最大値(ツリーノードのルート){ 10 であれば(ルート== NULL ) 11 リターン 0 。 12 INT左= Math.max(0、最大(root.left)); 13 int型の右= Math.max(0 、MAX(root.right))。 14 = Math.max和(総和は、+右+左root.val)を、 15 リターン Math.max(左、右)+ root.val。 16 } 17 }