繁体   English   中英

二叉搜索树中K个最小元素的总和

[英]Sum of K smallest elements in Binary search Tree

谁能建议,下面的代码在BST中查找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);
            }

那么,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

我认为您正在寻找类似的东西,这是我在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。

希望这可以帮助 !

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM