How to find the maximum difference between any two nodes in a Binary Tree - algorithm

Can somebody help me in understanding the below algorithm of how to find the maximum difference between any two nodes in a Binary Tree.
http://www.geeksforgeeks.org/maximum-difference-between-node-and-its-ancestor-in-binary-tree/
I'm not understanding why they are trying to get minimum value from left subtree and right subtree when in actual we want max difference & not min difference. So, Shouldn't we be getting the max difference recursively from left & right subtrees & use it to calculate our result?
Thanks in advance !!

To find maximum difference it suffices to subtract maximum from minimum. The link you provided is describing algorithm for a different problem: find maximum difference |A-B| where A is ancestor of B.

As usual, there are several ways of performing this, and yours might work just as well as the one presented by geeksforgeeks, though it seems harder to implement to me.
The maximum difference between the current node and any other is obtained by substracting the minimum value from the current subtree from the current value. This is why they are taking the minimum value of the right and left subtree. The maximum difference so far is contained in the ref pointer, which is updated if needed.

Related

Dynamic Programming on Binary Tree: Maximize data transmitted with limited edge capacity

Given a network of a binary tree of nodes with edge capacities c_e. There are data at the leaf nodes and each has data size s_v. L_e is the set of all leaves in the subtree below edge e. Our aim is to find subset S of leaves such that the number of data size transmitted to the root r is maximized, but for all the edges that the data passes through the capacity constraint must hold. It is assumed that c_e and s_v are non negative integers and let m be their maximum. Using dynamic programming on trees it should run in O(nm^2) time.
I have working on this for hours but haven't really come up woth a working solution. Any hints would be appreciated.
edit:
The data must be transmitted as a whole or not at all. for example if a leaf has 10 the algorithm can only take 10 or 0 at all.
for example,
v4=1, v5=3, v6=2, v7=2.
e1=(v1,r), e2=(v2,v1) and e3=(v3,v1) and so on.
assume that the capacity for e4, e5,e6 and e7 satisfied. But c1=5, c2=3 and c3=4
if we focused on finding the maximum of each subtree, we will end up taking v5 and v6+v7 which is not optimal. how to make dynamic programming rule that can tackle this problem and find the correct optimal solution?
Similar to the dynamic programming solution for subset sum...
For each node, calculate the set of attainable sums for subsets of the leaves, and for each attainable sum, remember the last contributing child and the previous sum. You can use this information to reconstruct the set that produces the sum.
While doing a postorder traversal of the tree, you can calculate this set for each node using only the information on its children.
When you get to the root, pick the maximum attainable sum and reconstruct the leaves that produce it.

Distance between two nodes in a tree weighted

My Question is very straight forward.
A weighted tree is given. We must find the distance between two given nodes.
since number of queries are very high(around 75000) each time bfs be timed out so I tried different way to do that.
My algorithm is like this :
I ran dfs from vertex 0 and calculated distance from root(0) to all vertex something like this
depth[v]=depth[u]+w,where u is parent of v and w is weight b/w (u,v)
Once I calculated depth of all node using dfs and 2^j th parent of each node(Assume I know how to do that).I calculated LCA for (u,v) asked for each query.
Then I calulated distance like this
distance between (u,v)=depth[u]+depth[v]-2*depth[lca(u,v)]
But I am not getting correct verdict as expected.Is my algorithm correct or am I missing something crucial.Guidance needed :)
P.s Incase anyone wants to see my implementation-Link http://paste.ubuntu.com/13129038/
Your approach sounds reasonable, but looking at the linked code I suggest you try a small example (e.g. with 3 nodes in the tree) and check the contents of the parent array carefully.
As far as I can see, the only lines changing the contents of the parent array are:
memset(parent,-1,sizeof parent);
and
parent[i][j]=parent[i-1][parent[i-1][j]]
so I believe the contents of parent will always equal -1.
Perhaps you need a base case setting parent[0][j] equal to the parent of j?
Also, it is not quite clear from the code whether you are using depth to mean a count of the number of edges, or a sum of the weights of all the edges. For the distance calculation to work you need a sum of weights, but for the LCA algorithm to work you may find you need to use the count of edges.

How do i find a path through a boolean array?

Here's a question I came across on an interview forum:
You have an array filled with 0s and 1s. A 0 represents burning lava,
and a 1 represents a stepping stone. You start at the beginning of the
array, and you want to find the fastest way to reach the end. At each
time step, you can either increase or decrease your velocity V by 1,
or you can jump to a stepping stone V steps away. You want to reach
the end of the array without overshooting.
What is a good algorithm to solve this?
I tried a few things (mostly using dynamic programming and recursion), but I couldn't figure out an optimal substructure that would lead to a non exponential algorithm. Any ideas?
At each step you have two choices: increasing velocity, or not increasing the velocity. Then, for each of these options, you end up at a different step and the choice repeats. Maybe you can see the tree pattern emerging here. Each node in the tree is a step and each edge is a choice. Each node (step) has two edges (choices), so it is a binary tree.
Also note that if you are at a step x with a velocity V, then it doesn't matter how you got there, the result of what follows will be the same. So here you can optimize a bit. (For example, using dynamic programming.)
The brute-force approach would be to just imagine this tree and do a depth-first search until you reach the end step exactly. There may be multiple solutions, and the fastest one is the solution.
Dynamic Programming is the right approach here.
Your search space is two-dimensional: the current position is your first dimension, and the current velocity is the second dimension. This means that you need a 2D array best[N][N], where N is the number of items in the boolean array. The value at best[s,v] represents the smallest number of steps required to reach position of s with the velocity of v. Examine each point of the search space to check if a stepping stone can be reached with the current velocity. If the answer is "yes", set the corresponding spot in the search space. Also set the points for adjacent speeds. The answer would be at the position best[N-1][0].

Finding kth largest path sum in a Binary Search Tree witout additional storage

Is there any way to find the kth largest of all possible full path sums in a binary search tree without using any other storage, like array? Initially I thought that if I go on finding the sum of paths from the right while increasing a pointer, with each new sum being the minimum as that and the previous sum (initially sum is infinite), breaking out when the count reaches k. However I just discovered that while the maximum leaf values be naturally sorted from right to left, the sums need not be so. So this method won't work. How can I do this?
If you can calculate the k-smallest then you can calculate the k-largest with the same algorithm. All you need to do is do things right-to-left instead of left-to-right.

Find connected-blocks with certain value in a grid

I'm having trouble finding an algorithm for my problem.
I have a grid of 8x8 blocks, each block has a value ranging from 0 to 9. And I want to find collections of connected blocks that match a total value of for example 15. My first approach was to start of at the border, that worked fine. But when starting in the middle of the grid my algorithm gets lost.
Would anyone know a simple algorithm to use or can you point me in the right direction?
Thanks!
As far as I know, no simple algorithm exists for this. As for pointing you in the right direction, an 8x8 grid is really just a special case of a graph, so I'd start with graph traversal algorithms. I find that in cases like this, it sometimes helps to think how you would solve the problem for a smaller grid (say, 3x3 or 4x4) and then see if your algorithm scales up to "full size."
EDIT :
My proposed algorithm is a modified depth-first traversal. To use it, you'll have to convert your grid into a graph. The graph should be undirected, since connected blocks are connected equally in both directions.
Each graph node represents a single block, containing the block's value and a visited variable. Edge weights represent their edges' resistance to being followed. Set them by summing the values of the nodes they connect. Depending on the sum you're looking for, you may be able to optimize this by removing edges that are guaranteed to fail. For example, if you're looking for 15, you can delete all edges with weight of 16 or greater.
The rest of the algorithm will be performed as many times as there are blocks, with each block serving as the starting block once. Traverse the graph by following the lowest-weighted edge from the current node, unless that takes you to a visited node. Push each visited node onto a stack and set its visited variable to true. Keep a running sum for every path followed.
Whenever the desired sum is reached, save the current path as one of your answers. Do not stop traversal, because the current node could be connected to a zero.
Whenever the total exceeds the desired sum, backtrack by setting visited to false and popping the current node off the stack.
Whenever all edges for a given node have been explored, backtrack.
After every possible path from a given starting node is analyzed, every answer that includes that node has been found. So, remove all edges touching the starting node and choose a new starting node.
I haven't fully analyzed the efficiency/running time of this algorithm yet, but... it's not good. (Consider the number of paths to be searched in a graph containing all zeroes.) That said, it's far better than pure brute force.

Resources