2017-05-04 16 views
0

BSTのk個の最小要素の合計を見つけるために、以下のコードを参考にしてください。ツリー内のすべてのノードの合計を返します。バイナリ検索ツリーのK個の最小要素の合計

public int findSum(Node root, int k){ 
      int count = 0; 
      return findSumRec(root, k, count); 
     } 

     private int findSumRec(Node root, int k, int count) { 

      if(root == null) 
       return 0; 
      if(count > k) 
       return 0; 

      int sum = findSumRec(root.left, k, count); 
      if(count >= k) 
       return sum; 

      sum += root.data; 
      count++; 

      if(count >= k) 
       return sum; 
      return sum + findSumRec(root.right, k, count); 
      } 
+0

これは、トラバースを唯一のelemsに制限するために、インオーダートラバーサルのコードを再利用しました –

+0

予想される出力は何ですか?あなたは代わりにどんな出力を得ていますか? – cyroxis

+1

あなたのコードはツリー内のすべての数字を追加しています。最小であるかどうかを確認するロジックは –

答えて

0

まあ、Javaは値言語によってパスがそれを呼び出したメソッドのcountの値を変更しない1回のメソッド呼び出しでcountの値を変更すること、です。

k5count4であるとき、あなたが呼び出している、再帰中のある時点で仮定します

 int sum = findSumRec(root.left, 5, 4); 

は、この呼び出しは5に、渡されたcountを増加させ、いくつかのsumを返すと仮定します。

今、あなたは戻ってfindSumRec(root.left, 5, 4)と呼ばれ、あなたがチェックする方法にある。最近返さ再帰呼び出しは、呼び出し側がまだcountを見て、あなたが行われるべきことを意味する、5までcountを持っていても

 if(4 >= 5) 
      return sum; 

4(これは同じcount変数ではないため)、したがって、ツリーのすべてのノードを参照してそれらのすべてを合計するまで、ツリーのトラバーサルは継続されます。

countを変更するには、いくつかの可変インスタンスを使用する必要があります。私はちょうど私の修正案であなたのコードをテストし、それが動作します:

public int findSum(Node root, int k){ 
    int[] count = {0}; 
    return findSumRec(root, k, count); 
} 

private int findSumRec(Node root, int k, int[] count) { 
    ... 
    change each count to count[0] 
    ... 
} 

EDIT:

はたとえば、1つの要素を持つ配列を使用することができます。

public int findSum(Node root, int k) { 
    int[] count = {0}; 
    return findSumRec(root, k, count); 
} 

private int findSumRec(Node root, int k, int[] count) { 

    if(root == null) 
     return 0; 
    if(count[0] > k) 
     return 0; 

    int sum = findSumRec(root.left, k, count); 
    if(count[0] >= k) 
     return sum; 

    sum += root.val; 
    count[0]++; 

    if(count[0] >= k) 
     return sum; 
    return sum + findSumRec(root.right, k, count); 
} 

点は、すべての再帰的方法はcount変数の値を共有し、それを変更することができなければならないfindSumRecにコールすることです。 countがメソッドに渡されたプリミティブ変数である場合、各メソッドはその変数の異なるコピーを取得するため、これは不可能です。

アレイの使用は1つのオプションです。別のオプションは、引数として渡す代わりに、メソッドを含むクラスのメンバ変数を使用することです。このようにしても、それはまだintです。 count_k_smallest_sum -

+0

もう少し詳しいことを教えてください。私の理解によれば、最初の呼び出しだけが "count = 0"を使用しているからです。その最初の呼び出しを残し、残っているすべての再帰呼び出しはcountの更新された値(各ノードの追加に対してcount ++)を使用して行われます。 – aman

+0

@aman_coder私は私の答えを詳述しました。私はあなたのコードを私の修正でテストしました。それはうまくいきました。それだけが問題でした。 – Eran

+0

ありがとうありがとう... :)今日のJavaについて本当に重要なことを学んだ.... :) – aman

-1

は、私はあなたがこのような何かを探していると思いますが、ここで

import java.io.*; 

public class Main { 

    public static class Node { 
    int val; 
    Node left; 
    Node right; 
    public Node(int data) { 
     this.val = data; 
     this.left = null; 
     this.right = null; 
    } 
    } 

    public static int sum_ans = 0; 

    public static int count_k_smallest_sum(Node root, int count, int k) 
    { 
    if(count>=k) 
    { 
     return 100005; 
    } 
    if(root.left == null && root.right == null) 
    { 
     sum_ans += root.val; 
     return count+1; 
    } 
    int cnt = count; 
    if(root.left != null) 
    { 
     cnt = count_k_smallest_sum(root.left, cnt, k); 
    } 
    if(cnt >= k) 
    { 
     return 100005; 
    } 
    sum_ans += root.val; 
    cnt++; 

    if(cnt >= k) 
    { 
     return 100005; 
    } 

    if(root.right != null) 
    { 
     cnt = count_k_smallest_sum(root.right, cnt, k); 
    } 

    return cnt; 
    } 

    public static void main(String args[]) throws Exception { 
    Node root = new Node(10); 
    Node left1 = new Node(5); 
    Node right1 = new Node(11); 
    Node left2 = new Node(3); 
    Node right2 =new Node(12); 
    Node left3 = new Node(2); 
    Node right3 = new Node(7); 
    Node right4 = new Node(4); 
    root.left = left1; 
    root.right = right1; 
    right1.right = right2; 
    left1.left = left2; 
    left1.right = right3; 
    left2.left = left3; 
    left2.right = right4; 
    int cnt = count_k_smallest_sum(root, 0, 3); 
    System.out.println(sum_ans); 
    } 
} 

方法で私のコードのロジックを参照してくださいjavaの

で私のコードです。

希望すると便利です。

+0

こんにちは@zenwraight、ソリューションを提供していただきありがとうございます。しかし、私は実装しようとしているアプローチで間違いを見つけることに興味があります。私はちょうどこれを達成するために再帰的なinorder traveralアプローチを使用しようとしています(あなたと非常に似ています)。 Eranによって提供された提案はそれを助けるかもしれませんが、依然として私は疑いがほとんどありません。 – aman

+0

@aman、それはあなたの疑いが解消されていいね:) – zenwraight

関連する問題