目次
124. バイナリツリーの最大パス合計 - LeetCode
バイナリ ツリー内の パスは、 シーケンス内の隣接するノードのすべてのペアの間にエッジがあるノードのシーケンスとして定義されます。同じノードはパス シーケンス内に 最大 1 回のみ出現できます 。パスには 少なくとも 1 つの ノードが含まれており、必ずしもルート ノードを経由する必要はありません。
パスの合計は 、パス内の各ノードの値の合計です。
バイナリ ツリーのルート ノードを指定すると
root
、その 最大パス合計を返します 。例 1:
入力: root = [1,2,3] 出力: 6 説明:最適なパスは 2 -> 1 -> 3 で、パスの合計は 2 + 1 + 3 = 6 です。例 2:
入力: root = [-10,9,20,null,null,15,7] 出力: 42 説明:最適なパスは 15 -> 20 -> 7 で、パスの合計は 15 + 20 + 7 = 42 です。ヒント:
- ツリー内のノードの数の範囲は次のとおりです。
[1, 3 * 104]
-1000 <= Node.val <= 1000
题解:
この問題では、バイナリ ツリー内のパスと最大パス合計、つまり、任意のノードから始まり、任意のノードを通過し、任意のノードに到着するパスの合計の最大値を計算する必要があります。
この問題を解決するには、バイナリ ツリーを再帰的にたどることができます。各ノードについて、ノードの最大寄与値、つまりノードがパスの一部であるときにノードが提供できる最大合計を計算する必要があります。
具体的な手順は次のとおりです。
maxSum
結果を保存する変数を作成します 。最初は負の無限大 (Integer.MIN_VALUE
) に設定されます。gain(TreeNode root)
ノードの最大寄与値を計算し、再帰中に値を更新する 再帰関数を定義しますmaxSum
。- 再帰関数ではまず終了条件を判定し、現在のノードが空の場合はそのまま0を返します。
- 左の子ノードと右の子ノードの最大寄与値をそれぞれ再帰的に計算し、その値と0の間の大きい方の値を取得します。これは、寄与値が負の場合、パス合計に対するゲインが 0 になるためです。
- 現在のノードの最大パス合計、つまりノード値と左右の子ノードの最大寄与値の合計を計算します。
- 現在のノードの最大パス合計を比較し
maxSum
、大きい方の値を更新しますmaxSum
。- 現在のノードの最大寄与値を返します。これは、ノード値に左右の子ノードの最大寄与値を加えた値のうち、大きい方の値です。
maxPathSum
関数 内でgain
ルートノードの最大寄与値を計算する関数を呼び出し、maxSum
その値を結果として返します。このようにして、再帰が終了すると、
maxSum
二分木におけるパス和と最大パス和が格納されることになる。
代码:
class Solution { // 存储结果 int maxSum =Integer.MIN_VALUE; public int maxPathSum(TreeNode root) { gain(root); return maxSum; } // 计算节点最大贡献值 public int gain(TreeNode root){ // 终止条件 if(root==null) return 0; // 递归计算左右子节点最大贡献值(结果为负数不计入) int left=Math.max(gain(root.left),0); int right=Math.max(gain(root.right),0); // 计算该结点的最大路径和 // 节点最大路径和为该节点的值与该节点左右子节点的最大贡献值 int max=root.val+left+right; //比较该节点的最大路径和与目前值(贪心算法) maxSum=Math.max(maxSum,max); // 返回该节点最大贡献值 return root.val+Math.max(left,right); } }
运行结果: