当前位置: 首页 > 知识库问答 >
问题:

Java:具有最小和的二叉树根到叶路径

子车桐
2023-03-14

我试图找到从根到叶的最小路径和,还需要计算最小路径。如果解决方案在左子树中,我的解决方案有效,但是如果结果在右子树中,根节点在结果路径中添加了两次,是否有人可以查看我的解决方案并帮助我修复此错误,如果有,还可以建议更好的运行时解决方案

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

import static java.lang.System.out;

public class MinPathSumFromRootToLeaf {

    public static void main(String[] args) {
        TreeNode root = new TreeNode(-1);
        TreeNode left1 = new TreeNode(2);
        TreeNode right1 = new TreeNode(1);//3
        TreeNode left2 = new TreeNode(4);
        root.left = left1;
        root.right = right1;
        left1.left = left2;
        TreeNode left3 = new TreeNode(0);//5
        TreeNode right3 = new TreeNode(1);//6
        right1.left = left3;
        right1.right = right3;
        left3.left = new TreeNode(0);//7
        right3.left = new TreeNode(8);
        right3.right = new TreeNode(1);//9
        printLevelOrder(root);
        shortestPathFromRootToLeaf(root);
    }

    private static void shortestPathFromRootToLeaf(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        int minsum[] = new int[1];
        minsum[0] = Integer.MAX_VALUE;
        backtrack(root, result, new ArrayList<>(), 0, minsum);
        out.println(result + " minsum " + minsum[0]);
    }

    private static void backtrack(TreeNode node, List<Integer> result, List<Integer> currentpath, int currentSum, int[] minsum) {
        if (node == null || currentSum > minsum[0]) {
            return;
        }
        if (node.left == null && node.right == null) {
            if (currentSum + node.val < minsum[0]) {
                minsum[0] = currentSum + node.val;
                currentpath.add(node.val);
                result.clear();
                result.addAll(new ArrayList<>(currentpath));
                return;
            }
        }
        if (node.left != null) {
            currentpath.add(node.val);
            backtrack(node.left, result, currentpath, currentSum + node.val, minsum);
            currentpath.remove(currentpath.size() - 1);
        }
        if (node.right != null) {
            currentpath.add(node.val);
            backtrack(node.right, result, currentpath, currentSum + node.val, minsum);
            currentpath.remove(currentpath.size() - 1);
        }
    }
    
    static class TreeNode {
    public int val;
    public TreeNode left;
    public TreeNode right;
    public TreeNode() {}
    public TreeNode(int val) { this.val = val; }
    public TreeNode(int val, TreeNode left, TreeNode right) {
          this.val = val;
          this.left = left;
          this.right = right;
      }
  }
    static class QItem {
        TreeNode node;
        int depth;

        public QItem(TreeNode node, int depth) {
            this.node = node;
            this.depth = depth;
        }
    }

    static void printLevelOrder(TreeNode root) {
        LinkedList<QItem> queue = new LinkedList<>();
        ArrayList<TreeNode> level = new ArrayList<>();
        int depth = height(root);
        queue.add(new QItem(root, depth));
        for (; ; ) {
            QItem curr = queue.poll();
            if (curr.depth < depth) {
                depth = curr.depth;
                for (int i = (int) Math.pow(2, depth) - 1; i > 0; i--) {
                    out.print(" ");
                }
                for (TreeNode n : level) {
                    out.print(n == null ? " " : n.val);
                    for (int i = (int) Math.pow(2, depth + 1); i > 1; i--) {
                        out.print(" ");
                    }
                }
                out.println();
                level.clear();
                if (curr.depth <= 0) {
                    break;
                }
            }
            level.add(curr.node);
            if (curr.node == null) {
                queue.add(new QItem(null, depth - 1));
                queue.add(new QItem(null, depth - 1));
            } else {
                queue.add(new QItem(curr.node.left, depth - 1));
                queue.add(new QItem(curr.node.right, depth - 1));
            }
        }
    }

    static int height(TreeNode root) {
        return root == null ? 0 : 1 + Math.max(
                height(root.left), height(root.right)
        );
    }

    static void printTree(TreeNode root) {
        Queue<TreeNode> q = new LinkedList<>();
        q.offer(root);
        while (!q.isEmpty()) {
            int size = q.size();
            for (int i = 0; i < size; i++) {
                TreeNode temp = q.poll();
                out.print(" " + temp.val + " ");
                if (temp.left != null) q.offer(temp.left);
                if (temp.right != null) q.offer(temp.right);
            }
            out.println();
        }
    }
    
}

我正在使用回溯访问所有节点,我认为我的解决方案的时间复杂度将是O(N)(因为所有节点都应该被访问,如果我错了,请纠正我)

共有1个答案

益稳
2023-03-14

每次调用currentpath。add应通过调用currentpath来镜像。删除。您的代码可以很好地执行此操作,但以下代码除外:

       if (node.left == null && node.right == null) {
            if (currentSum + node.val < minsum[0]) {
                minsum[0] = currentSum + node.val;
                currentpath.add(node.val);
                result.clear();
                result.addAll(new ArrayList<>(currentpath));
                return;
            }
        }

因此,在返回之前添加对remove的调用。

 类似资料:
  • 给定一棵二叉树,问题是找到所有根到叶的路径。我们通过以列表的形式传递路径,并在到达叶子时将其添加到结果中来了解算法。 我的问题是存储所有路径需要多少空间。我的直觉是,每条路径将消耗树高度(O(h))的内存顺序,如果我们的完整二叉树中有2*n-1个节点,那么每个节点对应于一条路径,因此假设树高度平衡,空间复杂度将为O(n*log(n))。我的分析正确吗?

  • 问题内容: 我试图使用Java在二叉树中打印所有根到叶的路径。 在主要方法中: 但是它给出了错误的输出。 给定的树: 预期产量: [5,1,3] [5、8、6] [5、8、9] 但是输出产生了: [5,1,3] [5、1、3、8、6] [5、1、3、8、6、9] 可以找出一个… 问题答案: 用以下方法调用递归方法: 传递时会发生什么(而不是在所有方法调用中使用单个对象,这意味着,当您返回原始调用者

  • 如何在二叉树中找到最小路径和,并打印路径?路径可以从ROOT节点到任何LEAF节点。我已经编写了C代码来查找最小和,但是在打印路径时遇到了问题。 参数列表中的未使用,有人能帮我打印路径和最小的路径吗?

  • 我试图搜索给定红黑树中所有根到叶的路径。特别是,我想编写一个测试,在给定rbt的情况下,该测试将断言每个路径具有相同数量的黑色节点。 我用两个全局变量尝试这样的东西: 然而,当左分支中的黑色节点右侧有红色节点时,我遇到了麻烦,因为这意味着计数比应该减少的更多。 有没有更好的方法来搜索根到叶的路径,计算特定值的频率,然后以某种方式比较计数?或者,如果给定rbt余额,是否有一种完全不同的方法来测试rb

  • 如何计算二叉树中最小级别所有叶节点的总和。如果不存在树,则应返回-1。 例子: 对于上述二叉树,返回100(40 60) (图片来源:Geeksforgeks)

  • 我必须获取二叉树中所有根到叶的路径。现在这通常是一项简单的任务,但现在我还必须识别左右节点。也就是说,当我进入节点的左子树时,该节点应记录在路径中为!abc,其中abc是节点名称。当进入右子树时,该节点应按原样记录。所以如果我的树是1(左)2(右)3,那么必须保存的两条路径是!1- 这确实获得了路径。但左右子树路径都连接在一起。也就是说,对于上面给出的示例,我得到[1,3,1,2]作为输出。我尝试