【发布时间】:2015-09-11 04:41:33
【问题描述】:
我正在努力寻找解决以下问题的算法:
给定一个整数的二叉树,一个分支(也就是从根开始并到达叶节点的分支)的成本由其值的总和给出。 编写一个返回最便宜分支列表的函数。
谁能推荐我完成这个练习的最简单方法?
【问题讨论】:
标签: algorithm data-structures tree linked-list binary-tree
我正在努力寻找解决以下问题的算法:
给定一个整数的二叉树,一个分支(也就是从根开始并到达叶节点的分支)的成本由其值的总和给出。 编写一个返回最便宜分支列表的函数。
谁能推荐我完成这个练习的最简单方法?
【问题讨论】:
标签: algorithm data-structures tree linked-list binary-tree
作为提示,从树的叶子向上工作。叶子的成本只是叶子内部的值。否则,从一个节点开始的最佳路径的成本由该节点的成本加上从该节点采取的最便宜路径的成本给出。你能递归实现吗?
希望这会有所帮助!
【讨论】:
由于树只是一个专门的图,Dijkstra 的算法在这里很有效:
https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm
只需跟踪最后哪个分支的成本最低。返回具有该分支的列表。
【讨论】:
我建议先遍历树的深度。
您将需要三个变量:
1)current cost,代表从根节点到当前节点的值之和。
2) cheapest path 从根到到目前为止的任何叶子(初始化为空)
3) cheapest cost 代表最便宜路径的成本
如果您到达一个节点,请将其节点成本添加到 current cost (1)。
如果您到达叶子,请将其节点成本也添加到current cost。然后检查它的成本是否比cheapest cost (3) 便宜。如果是(或不存在最便宜的成本,因为它是您到达的第一片叶子)设置cheapest cost = current cost。并将cheapest path 设置为当前路径(您可以将其存储在变量本身中,或者只是从当前离开向后遍历到根节点)
然后向上一个节点检查是否有一个你还没有访问过的分支。有的话就去看看。如果没有,请转到另一个节点并检查(依此类推...)
快捷方式:
当您到达一个节点并且它的current cost 大于cheapest cost 时,您可以跳过该节点的整个子树。
【讨论】:
您需要构建对的priority_queue(c++ stl 有这个容器):
优先级是成本,递增。
算法:
放入priority_queue pair(root, cost_of_root)。此后,循环:
就是这样。
【讨论】:
它可以很容易地递归完成。该函数打印所有根到叶路径以及最便宜的分支。我使用 Arraylist 将所有节点从根添加到叶。每当到达叶节点时,我只需检查到目前为止的 maxSum 是否小于当前根到叶路径并更新它。
class Node {
public int info;
public Node left;
public Node right;
public Node(int info) {
this(info, null, null);
}
public Node(int info, Node left, Node right) {
this.info = info;
this.left = left;
this.right = right;
}
}
public class RootToLeaf {
private static int maxSum = Integer.MAX_VALUE;
private static ArrayList<Integer> finalList = new ArrayList<>();
public static void main(String[] args) {
Node root = new Node(8);
root.left = new Node(4);
root.left.left = new Node(3);
root.left.right = new Node(1);
root.right = new Node(5);
root.right.right = new Node(11);
ArrayList<Integer> list = new ArrayList<Integer>();
path(root, list,0);
System.out.println("Cheapest list is - " + finalList.toString() + " and minimum sum is " + maxSum);
}
private static void path(Node root, ArrayList<Integer> list,int s) {
if(root==null) {
return;
} else {
list.add(root.info);
s = s+root.info;
}
if ((root.left == null && root.right == null)) {
System.out.println(list);
if(maxSum>s) {
maxSum = s;
finalList = new ArrayList<>(list);
}
return;
}
path(root.left, new ArrayList<Integer>(list),s);
path(root.right, new ArrayList<Integer>(list),s);
}
}
输出如下:
[8, 4, 3]
[8, 4, 1]
[8, 5, 11]
Cheapest list is - [8, 4, 1] and minimum sum is 13
【讨论】: