再帰メソッドで値を保持するために静的メンバー変数が機能しないのはなぜですか?

ランパード

LeetCodeOJで「SumofLeft Leaves」としてツリーの問題を解決しようとすると、次のような問題が発生します。

左の2つのノードのみが8と9であるツリーの例を考えると、予想される答えは17です。完全なツリーは、以下のmainメソッドを参照できます。

私が最初に書いた間違った答えは、静的メンバー変数「sum」を使用して現在の再帰の結果を格納し、パラメーターとして次の再帰に渡すことです。ただし、以下のコードのように、常に0を返します。

public class Solution {
   public TreeNode root;

   private static class TreeNode {
      private String val;
      private TreeNode left, right;
      public TreeNode(String x) {
         this.val = x;
      }
   }

   public static int sum = 0;
   public static int sumOfLeftLeaves(TreeNode root) {
      if(root == null) {
         return 0;
      }

      sumOfLeftLeavesRec(root, false, sum);
      return sum;
   }

   public static void sumOfLeftLeavesRec(TreeNode x, boolean isLeft, int sum) {
      if(x == null) {
          return;
      }

      if(x.left == null && x.right == null && isLeft) {
          sum += Integer.valueOf(x.val);
      }

      sumOfLeftLeavesRec(x.left, true, sum);
      // As debug model check, if just use static memeber variable sum could not
      // keep the value when return from deepest recursion, e.g when return from
      // node 8, the sum should be 8 and pass into new recursion on node 6(which
      // return from recursion of node 8), but real situation is sum will change
      // back to 0.
      sumOfLeftLeavesRec(x.right, false, sum);
   }

   public static void main(String[] args) {
     /*
      * The tree used for test
      *        1
      *      /   \
      *     2     3
      *    / \   /
      *   6   5 9
      *  /
      * 8
     */
     Solution s = new Solution();
     s.root = new TreeNode("1");
     s.root.left = new TreeNode("2");
     s.root.right = new TreeNode("3");
     s.root.left.left = new TreeNode("6");
     s.root.left.right = new TreeNode("5");
     s.root.left.left.left = new TreeNode("8");
     s.root.right.left = new TreeNode("9");

     int result = sumOfLeftLeaves(s.root);
     System.out.println(result);
   }
}

私がこのサイトで観察した正解は、Javaバージョンの2番目のソリューションです。これは「Summ」として新しいクラスを生成し、そのメンバー変数「sum」を使用して結果を格納し、次の再帰に渡します。テストすると、これは正常に機能します(以下のコード)。メインメソッドとサンプルツリーは同じです。

public class Solution {
   private class Accumulator{
      int sum = 0;
   }

   public int sumOfLeftLeaves(TreeNode root) {
      if(root == null) {
          return 0;
      }

      Accumulator accumulator = new Accumulator();

      sumOfLeftLeavesRec(root, false, accumulator);
      return accumulator.sum;
   }

   /* Pass in a sum variable as an accumulator */
   public void sumOfLeftLeavesRec(TreeNode x, boolean isLeft, Accumulator accumulator) {
      if(x == null) {
          return;
      }

      if(x.left == null && x.right == null && isLeft) {
          accumulator.sum += x.val;
      }

      sumOfLeftLeavesRec(x.left, true, accumulator);
      sumOfLeftLeavesRec(x.right, false, accumulator);
   }
}

問題は、なぜ静的メンバー変数がこの状況で機能しないのか、また、「アキュムレータ」がレコードに使用され、「合計」の結果を正常に渡すことができるため、新しいネストされたクラスを作成するのはなぜですか?機械的に、臨界点は何ですか?ありがとう

janith1024

あなたの場合、整数変数の合計を作成します。それは原始的で不変です。この不変変数をパラメーターとして渡すため、静的変数の合計は更新されないため、パラメーターの合計を削除します。これを試してください。

    public class Solution {
  public TreeNode root;

  private static class TreeNode {
    private String val;
    private TreeNode left, right;

    public TreeNode(String x) {
      this.val = x;
    }
  }

  public static int sum = 0;

  public static int sumOfLeftLeaves(TreeNode root) {
    if (root == null) {
      return 0;
    }

    sumOfLeftLeavesRec(root, false);
    return sum;
  }

  public static void sumOfLeftLeavesRec(TreeNode x, boolean isLeft) {
    if (x == null) {
      return;
    }

    if (x.left == null && x.right == null && isLeft) {
      sum += Integer.valueOf(x.val);
    }

    sumOfLeftLeavesRec(x.left, true);
    // As debug model check, if just use static memeber variable sum could not
    // keep the value when return from deepest recursion, e.g when return from
    // node 8, the sum should be 8 and pass into new recursion on node 6(which
    // return from recursion of node 8), but real situation is sum will change
    // back to 0.
    sumOfLeftLeavesRec(x.right, false);
  }

  public static void main(String[] args) {
     /*
      * The tree used for test
      *        1
      *      /   \
      *     2     3
      *    / \   /
      *   6   5 9
      *  /
      * 8
     */
    Solution s = new Solution();
    s.root = new TreeNode("1");
    s.root.left = new TreeNode("2");
    s.root.right = new TreeNode("3");
    s.root.left.left = new TreeNode("6");
    s.root.left.right = new TreeNode("5");
    s.root.left.left.left = new TreeNode("8");
    s.root.right.left = new TreeNode("9");

    int result = sumOfLeftLeaves(s.root);
    System.out.println(result);
  }
}

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

静的メソッドに適用したときにconstexpr属性が機能しないのはなぜですか?

分類Dev

このコードがクラスの静的メソッドで機能しないのはなぜですか?

分類Dev

非静的メンバー関数のアドレスをC ++のスレッドに渡すための余分な&があるのはなぜですか?

分類Dev

自分自身を(再帰的に)呼び出すメンバーメソッドが無限ループに入らないのはなぜですか?

分類Dev

このラムダ式がステートメントでは機能しないのに、メソッドでは機能するのはなぜですか?

分類Dev

メソッドが静的変数を指す変数を認識しないのはなぜですか?

分類Dev

形状のない `everywhere`コンビネータがメソッド内で機能するのに` val`では機能しないのはなぜですか?

分類Dev

UDPSocket.SendAsync()が機能するためにconnect()メソッドを必要とするのはなぜですか?

分類Dev

メソッドが終了した後、ラムダ式がスコープ変数値の囲みを保持するのはなぜですか?

分類Dev

Python-戻り値がないのに再帰呼び出しが変数をインクリメントするのはなぜですか?

分類Dev

メンバー変数が再帰戻り規則に従わないのはなぜですか?

分類Dev

2つの文字をカウントするこの再帰的なJavaメソッドが機能するのはなぜですか?

分類Dev

Selenium ExecuteScriptメソッドがSalesforceアプリケーションで機能しなくなったのに、ExecuteAsyncScriptは機能するのはなぜですか

分類Dev

Pythonのメソッドが機能しないのに、コードbeyodメソッドは機能するのはなぜですか?

分類Dev

再帰メソッドがtrueを返す場合、なぜ再帰呼び出しに入るのですか?

分類Dev

このJSコードがIE11でSVGをアニメーション化するために機能しないのはなぜですか?

分類Dev

バッテリーの状態をチェックするBroadcastReceiverが、registerReceiver()メソッドを使用しないと機能しないのはなぜですか?

分類Dev

静的で再帰的なJavaメソッドを返すことが機能しない

分類Dev

テキストファイルの最初の行を読み取るためにバッチスクリプトで使用される「set / p」メソッドが「for」ループの本体で機能しないのはなぜですか?

分類Dev

リンカがグローバル関数に対して複数定義されたシンボルを報告するのに、クラス静的メソッドを報告しないのはなぜですか

分類Dev

正しいメソッドオーバーロードを使用するために、null条件式を()で囲む必要があるのはなぜですか?

分類Dev

Javaが静的メソッドのオーバーライドを許可しないのはなぜですか?

分類Dev

メソッドの戻り値を変数に割り当てる必要がないのはなぜですか?

分類Dev

super()が__new__以外の静的メソッドで機能しないのはなぜですか?

分類Dev

コマンドが実数を追加するために機能しないのはなぜですか?

分類Dev

ポインターが変数であるときにポインターのメソッドが機能するのはなぜですか?

分類Dev

Javaで再帰メソッドを使用しているときに、サポートされていないクラスバージョンエラーが発生するのはなぜですか?

分類Dev

WebMvcConfigurerオーバーライドメソッドが機能しないのはなぜですか?

分類Dev

ループで変数を宣言した後、間違った出力があるのはなぜですか?-(WrongQuestion:再帰メソッドでPromisesを使用して変数を宣言する方法は?)

Related 関連記事

  1. 1

    静的メソッドに適用したときにconstexpr属性が機能しないのはなぜですか?

  2. 2

    このコードがクラスの静的メソッドで機能しないのはなぜですか?

  3. 3

    非静的メンバー関数のアドレスをC ++のスレッドに渡すための余分な&があるのはなぜですか?

  4. 4

    自分自身を(再帰的に)呼び出すメンバーメソッドが無限ループに入らないのはなぜですか?

  5. 5

    このラムダ式がステートメントでは機能しないのに、メソッドでは機能するのはなぜですか?

  6. 6

    メソッドが静的変数を指す変数を認識しないのはなぜですか?

  7. 7

    形状のない `everywhere`コンビネータがメソッド内で機能するのに` val`では機能しないのはなぜですか?

  8. 8

    UDPSocket.SendAsync()が機能するためにconnect()メソッドを必要とするのはなぜですか?

  9. 9

    メソッドが終了した後、ラムダ式がスコープ変数値の囲みを保持するのはなぜですか?

  10. 10

    Python-戻り値がないのに再帰呼び出しが変数をインクリメントするのはなぜですか?

  11. 11

    メンバー変数が再帰戻り規則に従わないのはなぜですか?

  12. 12

    2つの文字をカウントするこの再帰的なJavaメソッドが機能するのはなぜですか?

  13. 13

    Selenium ExecuteScriptメソッドがSalesforceアプリケーションで機能しなくなったのに、ExecuteAsyncScriptは機能するのはなぜですか

  14. 14

    Pythonのメソッドが機能しないのに、コードbeyodメソッドは機能するのはなぜですか?

  15. 15

    再帰メソッドがtrueを返す場合、なぜ再帰呼び出しに入るのですか?

  16. 16

    このJSコードがIE11でSVGをアニメーション化するために機能しないのはなぜですか?

  17. 17

    バッテリーの状態をチェックするBroadcastReceiverが、registerReceiver()メソッドを使用しないと機能しないのはなぜですか?

  18. 18

    静的で再帰的なJavaメソッドを返すことが機能しない

  19. 19

    テキストファイルの最初の行を読み取るためにバッチスクリプトで使用される「set / p」メソッドが「for」ループの本体で機能しないのはなぜですか?

  20. 20

    リンカがグローバル関数に対して複数定義されたシンボルを報告するのに、クラス静的メソッドを報告しないのはなぜですか

  21. 21

    正しいメソッドオーバーロードを使用するために、null条件式を()で囲む必要があるのはなぜですか?

  22. 22

    Javaが静的メソッドのオーバーライドを許可しないのはなぜですか?

  23. 23

    メソッドの戻り値を変数に割り当てる必要がないのはなぜですか?

  24. 24

    super()が__new__以外の静的メソッドで機能しないのはなぜですか?

  25. 25

    コマンドが実数を追加するために機能しないのはなぜですか?

  26. 26

    ポインターが変数であるときにポインターのメソッドが機能するのはなぜですか?

  27. 27

    Javaで再帰メソッドを使用しているときに、サポートされていないクラスバージョンエラーが発生するのはなぜですか?

  28. 28

    WebMvcConfigurerオーバーライドメソッドが機能しないのはなぜですか?

  29. 29

    ループで変数を宣言した後、間違った出力があるのはなぜですか?-(WrongQuestion:再帰メソッドでPromisesを使用して変数を宣言する方法は?)

ホットタグ

アーカイブ