Reputation: 888
I'm struggling to find an algorithm for the following problem:
Given a binary tree of integers, the cost of a branch (a.k.a. a branch that starts from the root and reaches the leaf node) is given by the sum of his values. Write a function that returns a list of the cheapest branch.
Can anyone recommend me the easiest way to complete this exercise?
Upvotes: 5
Views: 2853
Reputation: 7602
It can easily be done recursively . The function prints all the root to leaf paths along with the cheapest branch. I have used ArrayList
to add all the nodes from root to leaf. Whenever a leaf node is reached i just check if the maxSum so far is smaller than then the current root to leaf path and update it.
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);
}
}
The out put is as follows :
[8, 4, 3]
[8, 4, 1]
[8, 5, 11]
Cheapest list is - [8, 4, 1] and minimum sum is 13
Upvotes: 5
Reputation: 358
I would suggest traversing the tree depth first.
You will need three variables:
1) the current cost
, wich represents the sum of the values from the root node to the current node.
2) the cheapest path
from root to any leaf so far (init it empty)
3) the cheapest cost
which represent the cost of the cheapest path
If you reach a node, add its node cost to the current cost
(1).
If you reach a leaf, add its node cost as well to the current cost
. Then check, if its cost is cheaper than the cheapest cost
(3). If it is (or no cheapest cost exists because its the first leaf you reach) set cheapest cost = current cost
. and set the cheapest path
to the current path (you can store it in a variable itself or just traverse backwards from the current leave to the root node)
Then go one node up and check if there is a branch you have not yet visited. If there is, go check it. If not, go another node up and check (and so on...)
Shortcut:
When you reach a node and the current cost
to it is larger than the cheapest cost
, you can skip the whole subtree of that node.
Upvotes: 1
Reputation: 3891
You needed to build priority_queue (c++ stl has this container) of pairs:
Priority is cost, ascending.
Algorithm:
Put into the priority_queue pair(root, cost_of_root). Thereafter, loop:
That's all.
Upvotes: 1
Reputation: 91
Since a tree is just a specialized graph, Dijkstra's algorithm works great here:
https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm
Just keep track of which branch has the lowest cost at the end. Return a list with that branch.
Upvotes: 0
Reputation: 372784
As a hint, work from the leaves of the tree upward. The cost of a leaf is just the value inside the leaf. Otherwise, the cost of a the best path starting at a node is given by the cost of that node plus the cost of the cheapest path taken from there. Can you implement this recursively?
Hope this helps!
Upvotes: 3