面接での注目の質問 (二分木の最大パス)

パスは、 ツリー内の任意のノードから始まり、親ノードと子ノードに沿って接続し、任意のノードに到達するシーケンスとして定義されます。同じノードはパス シーケンス内に 最大 1 回出現します 。パスには 少なくとも 1 つの ノードが含まれており、必ずしもルート ノードを通過する必要はありません。

パスの合計は 、パス内の各ノードの値の合計です。

バイナリ ツリーのルート ノードを指定すると root 、その 最大パス合計、つまりすべてのパス上のノード値の最大合計を返します。

 入力: root = [1,2,3]出力: 6説明:最適なパスは 2 -> 1 -> 3 で、パスの合計は 2 + 1 + 3 = 6 です。

 二分木では難しい問題ですが、この問題を解くのは実はそれほど難しくありません。

       質問で定義されているパスの一般的な状況を考えてみましょう: 道路は下から上に伸び、最高点のノードに到達した後は下に伸びます。最高点のノードは変曲点と呼ばれますが、そのようなノードは上に存在しない可能性があります。変曲点の左側または右側を考慮する必要があります。それぞれを変曲点として考慮する必要があります。各ノードには、その変曲点を含むパスの最大合計があり、これは次の式で取得されます。

leftRree+rightTree+root.val

       ここで、leftTree/rightTree は、ルートの左ノードと右ノードとして、それぞれ変曲点の左半分の経路と変曲点の右半分の経路和である経路和に寄与します。すべてのノードが変曲点となるときの式を調べます。 の結果、そして最終的に最大値がとられます。明らかに、この式はその後の dfs の走査 (左、右、中央) の特性を持っています。 dfs( ) メソッドは現在のノードのルートであり、変曲の息子の半側パスの合計としてルートを返します

  • 基本的なケースは、null への再帰時に 0 を返すことです。
  • dfs を再帰的に呼び出して、左側と右側の息子の leftTree と rightTree をそれぞれ見つけます。
  • leftTree/rightTree を取得した後、この式を使用して、現在のノードが変曲点となる最大パス max を計算します。
  • グローバル最大パスと最大値を更新する
  • 戻り値は、変曲点の子としての現在のノード ルートの寄与値であり、次のようになります。
return root.val+Math.max(leftTree,rightTree);

つまり、ルートは、左と右のハーフ パスのうち大きい方を使用して、上部の変曲点までの長いハーフ パスを形成します。

  • dfs が終了すると、max の値が正しい結果になります。 

 : ツリー内のノードはすべて負である可能性があるため、寄与を取得するときに、それが負の数である場合は、単に 0 を取得します。これは、ノードが位置するサイド パスが最大パスの形成に関与しないことを意味します。

ソースコード:

    //维护一个全局变量
    int max=Integer.MIN_VALUE;
    public int maxPathSum(TreeNode root) {
     //对入参进行判断
     if(root==null){
         return 0;
     }
      dfs(root);
      return max;
    }
    public int dfs(TreeNode root){
        //递归结束条件
        if(root==null){
            return 0;
        }
        int leftTree=Math.max(dfs(root.left),0);
        int rightTree=Math.max(dfs(root.right),0);
        int all=leftTree+rightTree+root.val;
        //更新最大值
        max=Math.max(max,all);
        return root.val+Math.max(leftTree,rightTree);
    }

おすすめ

転載: blog.csdn.net/dfdbb6b/article/details/132421538