I want to find maximum sum of K connected nodes in a binary tree. I thought of doing this through memorizing, but I'm stuck.
Think about how the problem breaks down. A connected subgraph of a binary tree is itself a tree. In particular, there is a root of the the subgraph, and the children of the root are also trees.
So, consider the following related problem. Given the binary tree and a particular node X, what is the maximum sum of a subtree rooted at X, where the subtree has N nodes?
If you could answer that question for N=1 through N=i, then you can answer the same question for N=i+1 by fixing the node X, choosing j nodes from X's left child, and i-j nodes from X's right child, for some choice of 0<=j<=i. This illustrates the "optimal subproblem" property required for dynamic programming.
Related
(Binary search tree is a binary tree where each node can have 2 children atmost, the right being larger than the node, and the left should be smaller than the node.)
I have a theory that i want to disprove. It says that for any binary tree, the if we take a search path (call it S) to a leaf node, then any node on the LEFT of S must be smaller than any node on S, and any node of the RIGHT must be larger than any node on S. In other words: node on left < node on S < node on right. Is there any counter-example to disprove this theory?
For example if we have this tree:
A search path for node K would be M->F->H->K
The set of nodes on the left contains C, A, D, G
The set on the right contains V,S,P,T,X,W
What is a good counter example?
Thank you.
This isn't really an answer, but it wouldn't fit in a comment...
I think your definition of "binary search tree" is a bit lacking - after all, this would meet your definition:
B
\
C
/ \
A D
However, that's not a true binary search tree - your definition lacks the recursive relationship. In a binary search tree, all elements in the left subtree of a node are less than the node label, and all elements in the right subtree are greater - not just the immediate children.
Perhaps having a more precise definition would help you in thinking about your "theory".
I came across THIS geeksforgeeks post to find nodes at distance k from the given node in a binary tree.
I am not able to understand it even after spending multiple hours. Specially the part to find the nodes at distance k in ancestors.
Can someone please please help me with a small dry run on the code/algorithm in the geeksforgeeks post? Or any other easy to understand solution without using parent pointer?
Let's say the depth of target node is D.
If the nodes you want is in the subtree rooted with target node, their depth should be D+k.
After that, you need to find all ancestors of the target node.
For each ancestor, if the depth is d, the distance between this ancestor to the target node is D-d.
So the final step is to find nodes in the other subtree of this ancestor whose distance is k - (D-d).
Input:
a rooted tree with n nodes;
each node p has positive integer weight w(p);
a node can have more than two children.
Problem:
divide the tree into k subtrees/partitions (obviously by removing k-1 edges);
subtree weight W(p) is the weight of all the nodes in a subtree rooted at node p;
all the subtrees should be weighted as evenly as possible - the difference between min(W(p)) and max(W(p)) should be as small as possible.
I've yet to find a suitable algorithm for this. Where should I start? Tips, instructions and pseudocode appreciated.
Assume you can't modify the tree other than to remove edges to create subtrees.
First understand that you cannot guarantee that by simply removing edges that you will have subtrees within an arbitrary bound. You can create tree that when you split them there is no way to create subtrees within a target bound. For example:
a(b(c,d,e,f),g)
You cannot split that into two balanced sections. The best you can do is remove the edge from a to b:
a(g) and b(c,d,e,f)
Also this criteria is a little underdefined when k > 2. What is better a split 10,10,10,1 or 10,10,6,5?
But you can come up with a method to split trees up in the most balanced way possible.
Implement you tree such that each node holds a count of all of its children. You can add this pretty efficiently to any tree. ( E.g. when you add a node you have to iterate up the chain of parent node incrementing the count. Remove a node and you iterate up subtracting from the count )
Then starting from the root iterate down, in a breadth first manner until you find a set of nodes that dominate child nodes in a way that is most balanced. I don't have an algorithm for this at the ready - but I think you can find one pretty readily.
I think something where when you want to divide into k subtrees you create an array of k tree roots. One of those nodes must always be the root of the current tree, then you iterate down looking for nodes to replace on of the k-1 candidates that improves the partitioning. You'll want some kind of terminating condition where you don't interate down to every leaf node. E.g. it never makes sense to subdivide anything by the largest candidate node.
I am stuck up with a modified version of the problem ( Find two nodes located at a distance k in a binary tree).
I was trying to define the distance between two nodes and I believe that it is the minimum number of nodes needed to travel from node n1 to node n2 along the tree branches.
Well proceeding with this assumption, I arrived at a situation where I believe I need to know for each node if it is to the left or right of the root.
Case1 : If n1 and n2 are on different side then I climb to the root ( distance equals to depth of the node n1 - assuming n1 is on left) and then I run down to the right node n2 ( distance equals to the depth of n2). So the maximum distance between two nodes n1 , n2 is the sum of their depths if they are on different sides of the root.
Case 2 : If n1 and n2 are on the same side, I find an ancestor common to both in the tree hierarchy and repeat the same process considering the ancestor a root as I did in the case 1.
The minimum distance will be the sum of their depths from root - 2 times the depth of common ancestor.
Now, the problem with this is, I end up doing this for every pair of node bluntly. I can optimize it to not check a pair if I know a pair of node which are at a distance more than this but how?
Please suggest the rest of the solution.
Same problem as Diameter of a Binary Tree(see the bottom up approach) which is defined as the number of nodes on the longest path between two leaves in the tree. In your case you have to find out nodes as well.
Problem: I have a binary tree, all leaves are numbered (from left to right, starting from 0) and no connection exists between them.
I want an algorithm that, given two indices (of 2 distinct leaves), visits the tree starting from the greater leaf (the one with the higher index) and gets to the lower one.
The internal nodes of the tree do not contain any useful information.
I should chose the path based only on the leaves indices. The path start from a leaf and terminates on a leaf, and of course I can access a leaf if I know its index (through an array of pointers)
The tree is static, no insertion or deletion of nodes is allowed.
I have developed an algorithm to do it but it really sucks... any ideas?
One option would be to find the least common ancestor of the two nodes, along with the sequence of nodes you should take from each node to get to that ancestor. Here's a sketch of the algorithm:
Starting from each node, walk back up to that node's parent until you reach the root. Count the number of nodes on the path from each node to the root. Let the height of the first node be h1 and the height of the second node be h2.
Let h = min(h1, h2). This is the height of the higher of the two nodes.
Starting from each node, keep following the node's parent pointer until both nodes are at height h. Record the nodes you followed during this step. At this point, both nodes are at the same height.
Until you find a common node, keep marching upwards from each node to its parent. Eventually you will hit their common ancestor. At this point, follow the path from the first node up to this ancestor, then down the path from the ancestor down to the second node.
In the worst case, this takes O(h) time and O(h) space, where h is the height of the tree. For a balanced binary tree is this O(lg n) time and space, which is quite good.
If you're interested in a Much More Hardcore version of this algorithm, consider looking into Tarjan's Least Common Ancestors algorithm, which with linear preprocessing time, can be used to find the least common ancestor much more rapidly than this.
Hope this helps!
Distance between any two nodes can be calculated with the help of lowest common ancestor:
Dist(n1, n2) = Dist(root, n1) + Dist(root, n2) - 2*Dist(root, lca)
where lca is lowest common ancestor.
see this for more help about this algorithm and see this video for learning how to calculate lca.