2017-05-04 82 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

我會重複使用中間遍歷的代碼來限制遍歷到只有7個電子元件 –

+0

什麼是預期輸出和示例輸入?你得到什麼輸出? – cyroxis

+1

你的代碼是在樹中添加所有數字,其中是邏輯來驗證它是否最小 –

回答

0

那麼,Java是按值傳遞的語言,所以改變一個方法調用的count值不會改變調用它的方法count值。

假設在遞歸過程中的某個時刻,當k5count4,你在呼喚:

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

假設這個調用增加了count傳遞給它5,並返回一些sum

現在你又回到那個叫findSumRec(root.left, 5, 4)的方法和你檢查:

 if(4 >= 5) 
      return sum; 

即使最近返回遞歸調用帶來count高達5,這意味着你應該做的,調用者仍然認爲count作爲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] 
    ... 
} 

編輯:我剛剛與我的建議的校正測試你的代碼,它的工作原理。

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); 
} 

的一點是,所有的遞歸方法調用findSumRec必須共享count變量的值,並能夠改變它。當count是一個傳遞給方法的原始變量時,這是不可能的,因爲每個方法獲得該變量的不同副本。

使用數組是一種選擇。另一個選擇是使用包含您的方法的類的成員變量,而不是將其作爲參數傳遞。這樣它仍然可以是int

+0

您能否詳細闡述一下這個問題。因爲根據我的理解,只有最初的調用使用「count = 0」。發佈第一次調用後,剩下的所有遞歸調用都將使用count的更新值(每個節點添加的count ++)完成。 – aman

+0

@aman_coder我詳細闡述了我的答案。我用我的修復程序測試了您的代碼,並且它可以工作,所以這是唯一的問題。 – Eran

+0

非常感謝你...... :)今天學到了關於java的一些真正重要的東西.... :) – aman

-1

我認爲你正在尋找這樣的事情,這是我在Java

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); 
    } 
} 

看到我的方法的代碼邏輯代碼 - count_k_smallest_sum。

希望這會有所幫助!

+0

嘿@zenwraight,謝謝你提供的解決方案,它也工作得很好。但是,我有興趣找到我嘗試實施的方法中的錯誤。我只是試圖使用遞歸inorder traveral方法來實現這一點(非常類似於你的)。 Eran提供的建議可能會對此有所幫助,但我仍然沒有多少懷疑。 – aman

+0

@aman得到它,很高興你的懷疑被清除:) – zenwraight