ok i am given a bunch of leafs 10,9,7,8 and i need to create a sum tree from them as such
i need to find the sum of what is circled.
the problem is really a weight problem where i can choose two elements at a time to add them and their combined weight is the work done to combine the elements and i have to keep doing this till all the weights are combined while doing the minimum amount of work but i have turned it into this because i think this is the way to solve it.
is this the best way to solve this problem or is there a better way?
what would be the fastest way to create this tree and calculate the sum of those nodes?
The greedy solution:
Put all leaves in a priority queue (minimum weight comes out first).
While the queue contains more than one tree, pull out the two least-weight trees, join them and insert the joint tree into the queue.
When the queue contains only a single tree, that is your solution.
The greedy solution works:
Given any binary tree built from the leaves, each leaf contributes depth*weight to the total work/cost. (Where the depth of a leaf is the length of the path from the root to the leaf, e.g. in
18
/ \
3 15
/ \ / \
1 2 4 11
/ \
5 6
the leaves 1, 2, and 4 have depth 2, the leaves 5 and 6 have depth 3.)
So for any given shape of the tree, the smallest total cost is obtained when the lightest leaves are the deepest. Therefore a minimum cost tree is reached when the first step is joining the two lightest leaves to a new tree.
When some leaves have already been joined, the total cost of building the tree is (cost so far) + (cost of building cheapest tree considering the non-singleton trees as leaves).
So in the minimum cost tree, by the reasoning above, the two lightest "leaves" must be at the deepest level, hence can be joined to form a new subtree.
Use a stack machine. Push the leaves until the stack has 2 elements. Pop those elements, add (sub, mult, div, etc.) them, and push the result. Continuously do that until the input has no more elements. The final result is on top of the stack. This algorithm does arithmetic in the same order the sum tree would do it.
code stack
--------------------------
push 10 10$
push 9 9, 10$
pop a 10$
pop b $
push a+b 19$
push 7 7, 19$
push 8 8, 7, 19$
pop a 7, 19$
pop b 19$
push a+b 15, 19$
pop a 19$
pop b $
push a+b 34$
done 34$
Here is the implementation using Java
public static int sumTree(BinaryTreeNode<Integer> node) {
if (node == null) {
return 0;
}
int oldVal = node.getData();
node.setData(sumTree(node.getLeft()) + sumTree(node.getRight()));
return oldVal + node.getData();
}
Here is the test case
#Test
public void sumTreeTest() {
BinaryTreeNode<Integer> bt = BinaryTreeUtil.<Integer>fromInAndPostOrder(new Integer[]{8,-2,-4,10,7,6,5}, new Integer[]{8,-4,-2,7,5,6,10});
BinaryTreeUtil.sumTree(bt);
List<Integer> result = new ArrayList<Integer>();
BinaryTreeUtil.printInOrder(bt, result);
assertThat(result.toArray(new Integer[0]), equalTo(new Integer[]{0, 4, 0, 20, 0, 12, 0}));
//System.out.println(Arrays.toString(result.toArray()));
}
Related
Please bear with me I am very new to data structures.
I am getting confused how a priroity queue is used to solve min distance. For example if I have a matrix and want to find the min distance from the source to the destination, I know that I would perform Dijkstra algorithm in which with a queue I can easily find the distance between source and all elements in the matrix.
However, I am confused how a heap + priority queue is used here. For example say that I start at (1,1) on a grid and want to find the min distance to (3,3) I know how to implement the algorithm in the sense of finding the neighbours and checking the distances and marking as visited. But I have read about priority queues and min heaps and want to implement that.
Right now, my only understanding is a priority queue has a key to position elements. My issue is when I insert the first neighbours (1,0),(0,0),(2,1),(1,2) they are inserted in the pq based on a key (which would be distance in this case). So then the next search would be the element in the matrix with the shortest distance. But with the pq, how can a heap be used here with more then 2 neighbours? For example the children of (1,1) are the 4 neighbours stated above. This would go against the 2*i and 2*i + 1 and i/2
In conclusion, I don't understand how a min heap + priority queue works with finding the min of something like distance.
0 1 2 3
_ _ _ _
0 - |2|1|3|2|
1 - |1|3|5|1|
2 - |5|2|1|4|
3 - |2|4|2|1|
You need to use the priority queue to get the minimum weights in every move so the MinPQ will be fit for this.
MinPQ uses internally technique of heap to put the elements in the right position operations such as sink() swim()
So the MinPQ is the data structure that uses heap technique internally
If I'm interpreting your question correctly, you're getting stuck at this point:
But with the pq, how can a heap be used here with more then 2 neighbours? For example the children of (1,1) are the 4 neighbours stated above. This would go against the 2*i and 2*i + 1 and i/2
It sounds like what's tripping you up is that there are two separate concepts here that you may be combining together. First, there's the notion of "two places in a grid might be next to one another." In that world, you have (up to) four neighbors for each location. Next, there's the shape of the binary heap, in which each node has two children whose locations are given by certain arithmetic computations on array indices. Those are completely independent of one another - the binary heap has no idea that the items its storing come from a grid, and the grid has no idea that there's an array where each node has two children stored at particular positions.
For example, suppose you want to store locations (0, 0), (2, 0), (-2, 0) and (0, 2) in a binary heap, and that the weights of those locations are 1, 2, 3, and 4, respectively. Then the shape of the binary heap might look like this:
(0, 0)
Weight 1
/ \
(2, 0) (0, 2)
Weight 2 Weight 4
/
(0, -2)
Weight 3
This tree still gives each node two children; those children just don't necessarily map back to the relative positions of nodes in the grid.
More generally, treat the priority queue as a black box. Imagine that it's just a magic device that says "you can give me some new thing to store" and "I can give you the cheapest thing you've given be so far" and that's it. The fact that, internally, it coincidentally happens to be implemented as a binary heap is essentially irrelevant.
Hope this helps!
I am working on below interview question:
Given a singly linked list where elements are sorted in ascending
order, convert it to a height balanced BST.
For this problem, a height-balanced binary tree is defined as a binary
tree in which the depth of the two subtrees of every node never differ
by more than 1.
I am trying to understand below solution and its complexity? Can someone help me understand how it works? Is below solution O(n) time complexity and O(log n) space complexity?
Also is below algorithm better than "counting the number of nodes in the given Linked List. Let that be n. After counting nodes, we take left n/2 nodes and recursively construct the left subtree. After left subtree is constructed, we allocate memory for root and link the left subtree with root. Finally, we recursively construct the right subtree and link it with root. While constructing the BST, we also keep moving the list head pointer to next so that we have the appropriate pointer in each recursive call"
public TreeNode toBST(ListNode head) {
if(head==null) return null;
return helper(head,null);
}
public TreeNode helper(ListNode head, ListNode tail){
ListNode slow = head;
ListNode fast = head;
if(head==tail) return null;
while(fast!=tail && fast.next!=tail){
fast = fast.next.next;
slow = slow.next;
}
TreeNode thead = new TreeNode(slow.val);
thead.left = helper(head,slow);
thead.right = helper(slow.next,tail);
return thead;
}
BST-construction
A balanced tree can be constructed from a sorted list by subdividing the list into two equally long lists with one element in the middle being used as a root. E.g.:
1. [1, 2, 3, 4, 5, 6, 7]
2. 4
/ \
[1, 2, 3] [5, 6, 7]
3. 4
/ \
2 6
/ \ / \
1 3 5 7
Even if the two sublists differ by one element, they can at most differ by 1 in their height, thus making the tree balanced. By taking the middle element of the list the resulting tree is guaranteed to be a BST, since all smaller elements are part of the left subtree and all larger elements of the right subtree.
slow and fast
Your code works using two iterators, where one (fast) iterates over nodes twice as fast as the other (slow). So when fast has reached either the tail or the node right before the tail of the list, slow must be at the node in the middle of the list, thus dividing the list into two sublists of same length (up to at most one element difference), which can then be recursively processed as shown in the above diagramm.
Runtime Complexity
The algorithm runs in O(n lg n). Let's start with the recurrence of helper:
T(n) = n / 2 + 2 * T(n / 2)
T(1) = 1
In each call of helper, we must find the middle-node of the linkedlist defined by the two parameters passed to helper. This can only be done in n / 2 steps, since we can only walk linearly through the list. In addition, the helper is called recursively twice on linkedlists of half the size of the original list to build the left and right subtree.
Applying the Master-theorem(case 2) to the above recurrence, we get O(n lg n).
Space complexity
Space-complexity also needs to take the produced output-structure into account. Since each element of the input-linked list is converted into a node in the BST, the complexity is O(n).
EDIT
If the output is ignored, the space-complexity is solely dependent on the recursion-depth, which in turn is O(lg n), thus making the space-complexity O(lg n).
I'm new to the concept of graphs and trees.Below is the inorder tree traversal of tree.
if(n!=null){
treeTraversal(n.left);
System.out.println(n.val);
treeTraversal(n.right);
}
I'm not able to understand the flow as it involves recursion. Can somebody explain me how does control flow takes place with respect to stack.
Let's say I have a tree which is something like:
4
/ \
2 5
/ \
1 3
Your code will first put the recurse through the left children 4 -> 2 -> 1. Since 1 does not have a left child (it is null), it will print 1 and then pop the stack. Next up in the recursion is 2. It will print 2 then traverse the right child of 2 i.e 3. It will print 3, then pop the stack. Then it will print 4, then 4's right child 5. The sequence of prints will be 1, 2, 3, 4, 5. Here is a good animation too.
The image shows the execution of the code with a simple tree, it should help you to understand how recursion works, just follow the arrows.
Under each stack there is the tree diagram that shows in yellow the current node (click the image to expand it):
This is an inOrder traversal you first visit left child if exist if not you print the nod and the you travers to left node
for example in this tree your code out put will be
10, 4, 11, 2, 5, 9, 1, 7, 6, 8, 3
We have preOrder and postOrde traversal as well
preOrder
preorder(Node N)
if (N != null)
Visit N;
for each child Y of N
preorder(Y);
and post order
postorder(Node N)
if (N != null)
for each child Y of N
postorder(Y);
Visit N;
Suppose that there's a binary tree like the one below that needs to be stored in an array.
7
/ \
1 10
/\
9 11
And I found that the formula for storing the nodes in the array begins with storing the root node at position 0, and then for every node at index i, its children are placed at indices (i*2)+1 and (i*2)+2. And if the index of either child is greater than the array.length - 1, then that node does not have children.
So I begin by putting 7 at position 0, then its children 1 and 10 at position i2+1 and i2+2 which would be 1 and 2:
|7|1|10| | | |
0 1 2 3 4 5
Now, I'm stuck with node 1 which does not have any children. What should I put as its children?
Is it OK to put some default value that would represent the absence of a node, for example -1, like this:
|7|1|10|-1|-1|9|11|
0 1 2 3 4 5 6 7
This algorithm for storing a binary tree in an array is designed for trees such that every branch of the tree starting from the root node is of the same length: the array size is based on the greatest depth within the tree, and then it assigns an array position for every tree position of equal or lesser depth. If you have many different branch lengths, this may not be the correct algorithm for you. If your branch lengths are mostly the same depth but are sometimes empty near the end of the tree, placing a 'null' value such as -1 or Integer.MIN_VALUE may be an appropriate solution, as long as you know that you will not normally need to place any -1 values into the tree.
If you happen to know that you will only be missing elements from the greatest depth level of your tree (as in the example you provided), and the left/right order of the tree does not matter, you can instead simply reorder your tree such that the empty values are always in the bottommost, rightmost positions, which is also the set of positions at the end of your array, thus making your tree a complete binary tree. Then, you need only remember the number of elements in the tree, which is one greater than the index of the last non-null value. Diagrammed:
7
/ \
10 1
/\
9 11
-->
|7|10|1|9|11|0|0|
0 1 2 3 4 5 6
length = 5 or lastIndex = 4
I was thinking of using values which will break binary tree property at this point. In a general binary tree Left is always smaller and right is bigger than current node. If encounter higher on left or lower on right means end nodes.
i'm search a solution for the following task:
i have a flat list with a lot of data.
Now i want to transfrom this list into an tree with the following rules:
all of my listitems should be leafs
the number of nodes per tree depth should be limit the a certain limit
nodes can be nested with unlimited depth
i think it's like an k-ary (with k is the node limit per level) tree, but maybe this thing has annother name.
The background for this task is a visualisation problem of my list in a radial tree. Displaying all leafs on the first level in the radial tree doesn't look good when there are too much. So i think it's better to insert some nodes to group my data when the level limit is reached. The resulting tree should be able to display the leafs in a better visually way.
is there an algorithm or even better an implementation for this task?
Thanks for any pointer or infos.
Let's say N, the number of items in your list is 4 and K=2. So this will be a binary tree.
Step 1: Create 2 nodes
P1 P2
1 2 3 4
Step 2: Create links between the 2 nodes and K of the leaf nodes
P1 P2
/ \ / \
1 2 3 4
Step 3: Create another node
P5
P1 P2
/ \ / \
1 2 3 4
Step 4: Create the links between that node and the 2 previous nodes you created
P5
/ \
P1 P2
/ \ / \
1 2 3 4
See the pattern? You can do this iteratively pretty easily for any such N and K. You have to worry a little about cases where N is not a perfect power of K. Basically the number of children of every node is at most ceil(N/K).