タイトルのパスに続いて、時間と空間の複雑さに、解決策や課題のいくつかのアイデアを定義を拡張しました。
437パスの合計III
各ノードは、整数値を含むバイナリツリーを与えられています。
指定された値に合計パスの数を検索します。
パスは、開始またはルートまたはリーフで終了する必要はありませんが、それは(子ノードに親ノードからのみ旅行)下向きに行かなければなりません。
ツリーは、これ以上1,000ノードを有しており、値が1,000,000の範囲-1,000,000です。
例:
ルート= [10,5、-3,3,2、ヌル、11,3、-2、NULL、1]、和= 8
10
/ \
5 -3
/ \ \
3 2 11
/ \ \
3 -2 1
3.を返す8に合計パスは、次のとおりです。
1. 5 - > 3
2. 5 - > 2 - > 1
3 -3 - > 11
トピック分析:
この問題は、その子孫ノード、ソリューションのいずれかの、ほぼ1秒、非常にゆっくりと、しかし、単純な文言の割合、アイデアは、最も直接的なアプローチ、このプリオーダーDFSを、ツリーをトラバース呼び出しがあるルートにノードへのパスを延長します関数は、任意のサブノードまでノードからのパスを見つけ、そして合計か。この方法の低い効果の理由は、繰り返しトラバーサルがたくさんあります。
クラスのソリューション:
デフpathSum(自己、ルート:ツリーノード、合計:INT) - > int型:
「」」
:タイプのルート:ツリーノード
:タイプ合計:int型
:RTYPE:int型
「」」
デフDFS(ノード、合計):
DFSを返す(node.left、和node.val)+ DFS(node.right、和node.val)+(合計== node.val)他のノード0の場合
DFS(ルート、合計)+ self.pathSum(root.left、合計)+ self.pathSum(root.right、合計)他のルートの場合は0を返します
方法2は、非再帰的、スタック格納し、すべての親ノードを横断するためのフレームの後に、合計格納されたリストは、スタック一貫した和の開始ノードとしてのいずれかとパス(幾分類似動的プログラミング?)ので、長さ任意の数の和の合計に等しいとき、及び、経路要求が満たされます。トラバースの間、ノードは、対応する和はまた、脱積層、脱積層し、各デジタル値は、ノードを差し引きました。方法レート500msのが、空間的複雑さが実質的に上部では、99.9%を打ちます。
クラスのソリューション:
デフpathSum(自己、ルート:ツリーノード、合計:INT) - > int型:
ない場合はルート:
0を返します
スタック= []
合計= []
F = 0
RES = 0
P =ルート
真の中に:
P中:
stack.append(P)
sums.append(0)
範囲内のiについて(LEN(合計))。
合計[I] + = p.val
合計[i]を==合計の場合:
RES + = 1
P = p.left
前=なし
F = 1
スタックとF中:
P =スタック[-1]
p.right ==前の場合:
sums.pop()
範囲内のiについて(LEN(合計))。
和[1] - = p.val
stack.pop()
pの=
他:
P = p.right
F = 0
積み重ねない場合:
ブレーク
リターンRES
時間の見かけ上の複雑さは、それは非常にすることができ、我々は、52ms、新三人の大兄弟がそう見、多くの最適化のスペースがあります。解決策はまだある重複を避けるために、一度だけ横断するので、保存する必要があり、パスが登場している上に慎重に、大きなアイデアを把握しようと、このソリューションは、ハッシュマップを紹介します。私は、リストの値の合計にゆっくりと近づき、あなたがその役割を維持するために、一つ一つを減算する必要があり、辞書のキー操作により、同じsumMapアクションは、パフォーマンスの問題を解決します。このアイデアのいくつかの参照フレームワークは、上記の非再帰することができリライト。
クラスのソリューション:
デフpathSum(自己、ルート:ツリーノード、合計:INT) - > int型:
「」」
:タイプのルート:ツリーノード
:タイプ合計:int型
:RTYPE:int型
「」」
コレクションからdefaultdictをインポート
デフヘルパー(CUR、sumSoFar):
ローカル以外の解像度、sumMap
sumSoFar + = cur.val
sumSoFarは合計==場合:
RES + = 1 無錫婦人科病院http://www.ytsg120.cn
RES + = sumMap [sumSoFar - 和]
sumMap [sumSoFar] + = 1
cur.left場合:
ヘルパー(cur.left、sumSoFar)
cur.right場合:
ヘルパー(cur.right、sumSoFar)
sumMap [sumSoFar] - = 1
ない場合はルート:
0を返します
sumMap = defaultdict(INT)
RES = 0の場合root.val!=他合計1
sumMap [root.val] = 1
root.left場合:
ヘルパー(root.left、root.val)
root.right場合:
ヘルパー(root.right、root.val)
リターンRES
124バイナリツリーの最大パスの合計
非空のバイナリツリーを考えると、最大パスの合計を見つけます。
この問題のために、パスは親子接続に沿ってツリー内の任意のノードに、いくつかの開始ノードからノードの任意の配列として定義されます。パスは、少なくとも1つのノードが含まれている必要があり、ルートを通過する必要はありません。
例1:
入力:[1,2,3]
1
/ \
2 3
出力:6
例2:
入力:[-10,9,20、NULL、NULL、15,7]
-10
/ \
9 20
/ \
15 7
出力:42
トピック分析:
この質問は、私の意見では、大ボスのタイトルへの道であると考えられます。トピックは困惑し、最終的に私は他の経路問題とは別の、実際には、彼女自身の多くに、他の人の書き込みを見ました。私たちは、コードを見てください。
クラスのソリューション:
デフmaxPathSum(自己、ルート:ツリーノード) - > int型:
max_sum =フロート( " - INF")
デフヘルパー(ノード):
非ローカルmax_sum
ノードではない場合:
0を返します
lt_sum =ヘルパー(node.left)
rt_sum =ヘルパー(node.right)
local_sum = MAX(node.val、MAX(lt_sum、rt_sum)+ node.val)#1
max_sum = MAX(max_sum、MAX(local_sum、lt_sum + rt_sum + node.val))#2
local_sum戻ります
ヘルパー(ルート)
リターンmax_sum
まず、非常に異なる経路であり、必ずしもリーフノードを含まない対象は、必ずしもルートを含め、子の親への正しい道に子供に残される可能性があります。対象の結果は、グローバル変数であり、プロセスの先行順走査を解決する共通の問題は、再帰的プロセスは2つのことを達成された:まず、リターンlocal_sumは、最大かつ左または右のサブツリーです、コードは、ノード1と判断しました(一つだけを選択し)、それ自身、または左右のサブツリーと最大の一つと組み合わせるの最大値は、再帰方向の局所的な値は問題に対応し、経路を要求し、大きな問題は、そのような小さな問題に分解されます解決するために、2番目のものは、ノードに加えて最大左右のサブツリーの値を許可する今回max_sumを更新し、完全なパスが形成され、最大の値を変更することが決定されていないです。