Sway of Binary Tree - recursion

Original Problem
The problem is as stated and my solution is below: Return the amount a BST tree sways in one direction.
Sway is denoted by the amount of nodes that are
"unbalanced" - nullptr on only one side, a left
swaying tree returns the negative amount it sways
with any right sway offsetting the left and vice versa
int tree_sway(Node * node){
if(!node){
return 0;
}
int m = tree_sway(node->right) + 1;
int n = tree_sway(node->left) - 1;
return m - n;
}
For the tree sway problem, is the solution I have posted correct? If not, would the only way to do this problem be to create a helper function that keeps track of how many left and right turns the recursive step makes?

The code that you have posted is not quite correct. For example, on a tree with a root and a leaf, the result will always be 0 regardless of which side the leaf is on. One way of doing it this:
int tree_swap(Node *node) {
# base case of the recursion
if (!node) { return 0; }
# go down the left and right branches and add their scores
int score = tree_swap(node->left) + tree_swap(node->right);
# adjust the score for the missing children of the current node
if (!node->left) { score++; }
if (!node->right) { score--; }
return score;
}
The general idea is that as you recurse, you first go all the way down the tree and as you come back up you count the missing left and right branches and pass the running tally up the tree.

Related

Calculating number of nodes in BST using recursion c++

I'm trying to find the number of nodes in a BST using recursion. Here is my code
struct Node{
int key;
struct Node* left;
struct Node* right;
Node(){
int key = 0;
struct Node* left = nullptr;
struct Node* right = nullptr;
}
};
src_root is the address of the root node of the tree.
int BST::countNodes(Node* src_root, int sum){
if((src_root==root && src_root==nullptr) || src_root==nullptr)
return 0;
else if(src_root->left==nullptr || src_root->right==nullptr)
return sum;
return countNodes(src_root->left, sum + 1) + countNodes(src_root->right, sum + 1) + 1;
}
However my code only seems to work if there are 3 nodes. Anything greater than 3 gives wrong answer. Please help me find out what's wrong with it. Thanks!
It is a long time ago since I made anything in C/C++ so if there might be some syntax errors.
int BST::countNodes(Node *scr_root)
{
if (scr_root == null) return 0;
return 1 + countNodes(scr_root->left) + countNodes(scr_root->right);
}
I think that will do the job.
You have several logical and structural problems in your implementation. Casperah gave you the "clean" answer that I assume you already found on the web (if you haven't already done that research, you shouldn't have posted your question). Thus, what you're looking for is not someone else's solution, but how to fix your own.
Why do you pass sum down the tree? Lower nodes shouldn't care what the previous count is; it's the parent's job to accumulate the counts from its children. See how that's done in Casperah's answer? Drop the extra parameter from your code; it's merely another source for error.
Your base case has an identically false clause: src_root==root && src_root==nullptr ... if you make a meaningful call, src_root cannot be both root and nullptr.
Why are you comparing against a global value, root? Each call simply gets its own job done and returns. When your call tree crawls back to the original invocation, the one that was called with the root, it simply does its job and returns to the calling program. This should not be a special case.
Your else clause is wrong: it says that if either child is null, you ignore counting the other child altogether and return only the count so far. This guarantees that you'll give the wrong answer unless the tree is absolutely balanced and filled, a total of 2^N - 1 nodes for N levels.
Fix those items in whatever order you find instructive; the idea is to learn. Note, however, that your final code should look a lot like the answer Casperah provided.

how to rewrite the recursive solution to iterative one

The problem is derive from OJ.
The description is :
We are playing the Guess Game. The game is as follows:
I pick a number from 1 to n. You have to guess which number I picked.
Every time you guess wrong, I'll tell you whether the number I picked is higher or lower.
However, when you guess a particular number x, and you guess wrong, you pay $x. You win the game when you guess the number I picked.
Given a particular n ≥ 1, find out how much money you need to have to guarantee a win.
I write small snippet about MinMax problem in recursion. But it is slow and I want to rewrite it in a iterative way. Could anyone help with that and give me the idea about how you convert the recursive solution to iterative one? Any idea is appreciated. The code is showed below:
public int getMoneyAmount(int n) {
int[][] dp = new int[n + 1][n + 1];
for(int i = 0; i < dp.length; i++)
Arrays.fill(dp[i], -1);
return solve(dp, 1, n);
}
private int solve(int[][] dp, int left, int right){
if(left >= right){
return 0;
}
if(dp[left][right] != -1){
return dp[left][right];
}
dp[left][right] = Integer.MAX_VALUE;
for(int i = left; i <= right; i++){
dp[left][right] = Math.min(dp[left][right], i + Math.max(solve(dp, left, i - 1),solve(dp, i + 1, right)));
}
return dp[left][right];
}
In general, you convert using some focused concepts:
Replace the recursion with a while loop -- or a for loop, if you can pre-determine how many iterations you need (which you can do in this case).
Within the loop, check for the recursion's termination conditions; when you hit one of those, skip the rest of the loop.
Maintain local variables to replace the parameters and return value.
The loop termination is completion of the entire problem. In your case, this would be filling out the entire dp array.
The loop body consists of the computations that are currently in your recursion step: preparing the arguments for the recursive call.
Your general approach is to step through a nested (2-D) loop to fill out your array, starting from the simplest cases (left = right) and working your way to the far corner (left = 1, right = n). Note that your main diagonal is 0 (initialize that before you get into the loop), and your lower triangle is unused (don't even bother to initialize it).
For the loop body, you should be able to derive how to fill in each succeeding diagonal (one element shorter in each iteration) from the one you just did. That assignment statement is the body. In this case, you don't need the recursion termination conditions: the one that returns 0 is what you cover in initialization; the other you never hit, controlling left and right with your loop indices.
Are these enough hints to get you moving?

what is the difference of these two implementations of a recursion algorihtm?

I am doing a leetcode problem.
A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below).
The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked 'Finish' in the diagram below).
How many possible unique paths are there?
So I tried this implementation first and got a "exceeds runtime" (I forgot the exact term but it means the implementation is slow). So I changed it version 2, which use a array to save the results. I honestly don't know how the recursion works internally and why these two implementations have different efficiency.
version 1(slow):
class Solution {
// int res[101][101]={{0}};
public:
int uniquePaths(int m, int n) {
if (m==1 || n==1) return 1;
else{
return uniquePaths(m-1,n) + uniquePaths(m,n-1);
}
}
};
version2 (faster):
class Solution {
int res[101][101]={{0}};
public:
int uniquePaths(int m, int n) {
if (m==1 || n==1) return 1;
else{
if (res[m-1][n]==0) res[m-1][n] = uniquePaths(m-1,n);
if (res[m][n-1]==0) res[m][n-1] = uniquePaths(m,n-1);
return res[m-1][n] + res[m][n-1];
}
}
};
Version 1 is slower beacuse you are calculating the same data again and again. I'll try to explain this on different problem but I guess that you know Fibonacci numbers. You can calculate any Fibonacci number by following recursive algorithm:
fib(n):
if n == 0 then return 0
if n == 1 then return 1
return fib(n-1) + fib(n-1)
But what actually are you calculating? If you want to find fib(5) you need to calculate fib(4) and fib(3), then to calculate fib(4) you need to calculate fib(3) again! Take a look at the image to fully understand:
The same situation is in your code. You compute uniquePaths(m,n) even if you have it calculated before. To avoid that, in your second version you use array to store computed data and you don't have to compute it again when res[m][n]!=0

Minimum number of jumps required to climb stairs

I recently had an interview with Microsoft for an internship and I was asked this question in the interview.
Its basically like, you have 2 parallel staircases and both the staircases have n steps. You start from the bottom and you may move upwards on either of the staircases. Each step on the staircase has a penalty attached to it.
You can also move across both the staircases with some other penalty.
I had to find the minimum penalty that will be imposed for reaching the top.
I tried writing a recurrence relation but I couldn't write anything because of so many variables.
I recently read about dynamic programming and I think this question is related to that.
With some googling, I found that this question is the same as
https://www.hackerrank.com/contests/frost-byte-final/challenges/stairway
Can you please give a solution or an approach for this problem ?
Create two arrays to keep track of the minimal cost to reach every position. Fill both arrays with huge numbers (e.g. 1000000000) and the start of the arrays with the cost of the first step.
Then iterate over all possible steps, and use an inner loop to iterate over all possible jumps.
foreach step in (0, N) {
// we're now sure we know minimal cost to reach this step
foreach jump in (1,K) {
// updating minimal costs here
}
}
Now every time we reach updating there are 4 possible moves to consider:
from A[step] to A[step+jump]
from A[step] to B[step+jump]
from B[step] to A[step+jump]
from B[step] to B[step+jump]
For each of these moves you need to compute the cost. Because you already know that you have the optimal cost to reach A[step] and B[step] this is easy. It's not guaranteed this new move is an improvement, so only update the target cost in your array if the new cost is lower then the cost already there.
Isn't this just a directed graph search? Any kind of simple pathfinding algorithm could handle this. See
https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm
https://en.wikipedia.org/wiki/A*_search_algorithm
Just make sure you enforce the directional of the stairs (up only) and account for penalties (edge weights).
Worked solution
Of course, you could do it with dynamic programming, but I wouldn't be the one to ask for that...
import java.io.;
import java.util.;
public class Main {
public static int csmj(int []a,int src,int[] dp){
if(src>=a.length){
return Integer.MAX_VALUE-1;
}
if(src==a.length-1){
return 0;
}
if(dp[src]!=0){
return dp[src];
}
int count=Integer.MAX_VALUE-1;
for(int i=1;i<=a[src];i++){
count = Math.min( count , csmj(a,src+i,dp)+1 );
}
dp[src] = count;
return count;
}
public static void main(String args[] ) throws Exception {
Scanner s = new Scanner(System.in);
int n = s.nextInt();
int a[] = new int[n];
for(int i=0;i<n;i++){
a[i] = s.nextInt();
}
int minJumps = csmj(a,0,new int[n]);
System.out.println(minJumps);
}
}
bro you can have look at that solution my intuition is that

Connectivity of a Graph

int dfs(int graph[MAXNODES][MAXNODES],int visited[],int start) {
int stack[MAXNODES];
int top=-1,i;
visited[start]=1;
stack[++top]=start;
while(top!=-1)
{
start=stack[top];
for(i=0;i<MAXNODES;i++) {
if(graph[start][i]&&visited[i]==0) {
stack[++top]=i;
printf("%d-",i);
visited[i]=1;
break;
}
}
if(i==MAXNODES)
top--;
}
return 0;
}
The above code implements the dfs on a Graph stored as an Adjacency Matrix, I request a suggestion, what change should i be doing to know whether the generated graph is connected or not.
See my answer to an earlier question about strongly connected components.
Your dfs is also very inefficient as written, because you start over scanning at i=0 repeatedly; your stack should remember where you left off and continue from there. Recursion is more natural, but if you have bounded call stack size, then an explicit stack is best (for huge trees only).
Here's a recursive dfs. If you're not interested in storing the dfs tree, you can just store 1 in predecessor[] instead of the node you reached it from):
const unsigned MAXNODES=100;
/* predecessor must be 0-initialized by the caller; nodes graph[n] that are
reached from start will have predecessor[n]=p+1, where graph[pred] is the
predecessor via which n was reached from graph[start].
predecessor[start]=MAXNODES+1 (this is the root of the tree; there is NO
predecessor, but instead of 0, I put a positive value to show that it's
reached).
graph[a][b] is true iff there is a directed arc from a->b
*/
void dfs(bool graph[MAXNODES][MAXNODES],unsigned predecessor[]
,unsigned start,unsigned pred=MAXNODES)
{
if (predecessor[start]) return;
predecessor[start]=pred+1;
for (unsigned i=0;i<MAXNODES;++i)
if (graph[start][i])
dfs(graph,predecessor,i,start);
}
Here's a non-recursive dfs patterned on the above, but using the same stack variable for pred and i (in general you'd have a stack variable for every local variable and parameter that can change in your recursion):
void dfs_iter(bool graph[MAXNODES][MAXNODES],unsigned predecessor[]
,unsigned start)
{
unsigned stack[MAXNODES]; // node indices
unsigned n,pred;
int top=0;
stack[top]=start;
for(;;) {
recurse:
// invariant: stack[top] is the next (maybe reached) node
n=stack[top];
if (!predecessor[n]) { // not started yet
pred=top>0?stack[top-1]:MAXNODES;
//show(n,pred);
predecessor[n]=pred+1;
// the first thing we can reach from n
for (unsigned i=0;i<MAXNODES;++i)
if (graph[n][i] && !predecessor[i]) {
stack[++top]=i; goto recurse; // push
}
}
if (top>0) {
pred=stack[top-1];
// the next thing we can reach from pred after n
for (unsigned i=n+1;i<MAXNODES;++i)
if (graph[pred][i]) {
stack[top]=i; goto recurse; // replace top
}
--top;
} else
return;
}
}
This could be structured without the goto (it's just a named continue to the outmost loop), but without any more real clarity in my opinion.
Anyway, recursive calls are far simpler. There's recursive pseudocode for Tarjan's strongly connected components algorithm you can transcribe fairly directly. If you need help making it non-recursive (explicit stack), ask.
You'd need to store the edges generated by travelling from one node to the next. Then you could verify that all the nodes in the graph are connected by edges.
Run Dijkstra's algorithm. If at the end your queue is empty and some of the vertices aren't colored your graph isn't connected. This is guaranteed linear time, the dfs approach has a worst case analysis of quadratic.

Resources