lowest common ancestor in binary tree (strange behaviour of recursive function) - recursion

Here's the code which I submitted on gfg and it worked perfectly fine. But I can't figure out how it is working even when its not returning anything. How the variable 'avail' is becoming '-2' in any recursive call becoz the function is not returning anything.
/* A binary tree node
struct Node
{
int data;
struct Node* left;
struct Node* right;
Node(int x){
data = x;
left = right = NULL;
}
};
*/
class Solution
{
public:
// Function to return the lowest common ancestor in a Binary Tree.
int recursion(Node *p, int a, int b, Node *&answer)
{
if (p == nullptr)
return 0;
int avail;
if (p->data == a or p->data == b)
{
avail = -1;
avail = recursion(p->left, a, b, answer) + recursion(p->right, a, b, answer) + (-1);
}
else
avail = recursion(p->left, a, b, answer) + recursion(p->right, a, b, answer);
if (avail == -2)
{
answer = p;
}
// return 1;
}
Node *lca(Node *root, int n1, int n2)
{
Node *answer;
recursion(root, n1, n2, answer);
return answer;
}
};

Related

Why Complete LinkedList Reversed?

For Input 1->2->2->4->5->6->7->8
My output is 8 7 6 5 4 2 2 1 but I don't know why?
LINK OF PROBLEM IS BELOW :
https://practice.geeksforgeeks.org/problems/reverse-a-linked-list-in-groups-of-given-size/1
Reverse a Linked List in groups of given size.
Given a linked list of size N. The task is to reverse every k nodes (where k is an input to the function) in the linked list. If the number of nodes is not a multiple of k then left-out nodes, in the end, should be considered as a group and must be reversed (See Example 2 for clarification).
Example 1:
Input:
LinkedList: 1->2->2->4->5->6->7->8
K = 4
Output: 4 2 2 1 8 7 6 5
Explanation:
The first 4 elements 1,2,2,4 are reversed first
and then the next 4 elements 5,6,7,8. Hence, the
resultant linked list is 4->2->2->1->8->7->6->5.
Example 2:
Input:
LinkedList: 1->2->3->4->5
K = 3
Output: 3 2 1 5 4
Explanation:
The first 3 elements are 1,2,3 are reversed
first and then elements 4,5 are reversed.Hence,
the resultant linked list is 3->2->1->5->4.
Your Task:
You don't need to read input or print anything. Your task is to complete the function reverse() which should reverse the linked list in group of size k and return the head of the modified linked list.
Expected Time Complexity : O(N)
Expected Auxilliary Space : O(1)
Constraints:
1 <= N <= 104
1 <= k <= N
MY CODE BELOW:
//{ Driver Code Starts
#include<bits/stdc++.h>
using namespace std;
struct node
{
int data;
struct node* next;
node(int x){
data = x;
next = NULL;
}
};
/* Function to print linked list */
void printList(struct node *node)
{
while (node != NULL)
{
printf("%d ", node->data);
node = node->next;
}
printf("\n");
}
// } Driver Code Ends
/*
Reverse a linked list
The input list will have at least one element
Return the node which points to the head of the new LinkedList
Node is defined as
struct node
{
int data;
struct node* next;
node(int x){
data = x;
next = NULL;
}
}*head;
*/
class Solution
{
node* reverseHelper(node* head){
node* pre = NULL;
node* curr = head;
while(curr!=NULL){
node* nextTocurr = curr->next;
curr->next = pre;
pre = curr;
curr = nextTocurr;
}
return pre;
}
public:
struct node *reverse (struct node *head, int k)
{
// Complete this method
if(head==NULL|| head->next==NULL){
return head;
}
int count = 0;
node* tail = head;
while(count<k || tail->next!=NULL){
tail = tail->next;
count++;
}
node* head2 = tail->next;
tail->next = NULL;
node* ans = reverseHelper(head);
head->next = reverse(head2,k);
return ans;
}
};
//{ Driver Code Starts.
/* Drier program to test above function*/
int main(void)
{
int t;
cin>>t;
while(t--)
{
struct node* head = NULL;
struct node* temp = NULL;
int n;
cin >> n;
for(int i=0 ; i<n ; i++)
{
int value;
cin >> value;
if(i == 0)
{
head = new node(value);
temp = head;
}
else
{
temp->next = new node(value);
temp = temp->next;
}
}
int k;
cin>>k;
Solution ob;
head = ob.reverse(head, k);
printList(head);
}
return(0);
}
// } Driver Code Ends
The problem is in this loop:
int count = 0;
while(count<k || tail->next!=NULL){
It has two issues:
The loop will continue until the end of the list because the second condition will be true until that end is reached. The logical OR (||) should be a logical AND (&&), because you want both conditions to be true, not just one.
When the previous point is corrected, the loop will still iterate one time too many, because the head node was already considered to be included in the "slice". Correct by initialising count=1.
With those two corrections your code will work as intended.

TLE on UVA 10776 - Determine The Combination

I tried this problem by backtracking and did some optimization, though I am getting TLE. what further optimization can I do on this code?
Abridged problem statement - Task is to print all different r combinations of a string s (a r combination of a string s is a collection of exactly r letters from different positions in s).There may be different permutations of the same combination; consider only the one that has its r
characters in non-decreasing order. If s = "abaa" and s = 3.Then output should be (aaa,aab).
My code(in c)
int compare_chars(const void* a, const void* b);
char s[50];
int len;
int r ;
char combination[50];
void combinate(int index,int at)
{
if(at == r)
{
combination[at] = '\0';
puts(combination);
return ;
}
int i = index+1;
for ( ; i <= len-r+at ;)
{
char temp = s[I];
combination[at] = temp;
combinate(i,at+1);
while(s[i] == temp and i <= len-r+at)
i++;
}
return ;
}
int solve()
{
while ((scanf("%s %i",s,&r)) == 2)
{
len = strlen(s);
if(len == r)
{
printf("%s\n",s);
continue;
}
qsort(s,len,sizeof(char),compare_chars);
combinate(-1,0);
}
return 0;
}
int main()
{
int a = 1;
int t = 1;
while (a <= t)
{
int kk = solve();
}
return 0;
}
int compare_chars(const void* a, const void* b)
{
char arg1 = *(const char*)a;
char arg2 = *(const char*)b;
if (arg1 < arg2) return -1;
if (arg1 > arg2) return 1;
return 0;
}

Subtrees of height h in Binary tree

How do we find number of subtrees of height 'h' in a binary tree.
Function is defined as
int subtree( node *root, int k);
where k is the specific height.
First, we recursively calculate the height of the tree as follows:
If the tree is empty, the height is 0.
If the tree is non-empty, the height is the maximum height of its children, plus 1.
In C (I assume OP is using C based on response), this looks like
typedef struct Node {
Node* leftChild,
node* rightChild
} Node;
typedef Node* Tree;
unsigned int max(unsigned int a, unsigned int b) {
return a > b ? a : b;
}
unsigned int height(Tree tree) {
return tree ? 1 + max(height(tree->leftChild, tree->rightChild)) : 0;
}
Note that generally, Node will have some additional data. But that data isn't relevant here, so we don't include it (although it's easy enough to do so if you wish to).
Now, we want to modify the height function slightly. To do this, we define
typdef struct Result {
unsigned int height,
unsigned int count
} Result;
/**
* The returned .height should be the height of the tree.
* The returned .count should be the number of subtrees of tree
* with height k.
*/
Result resultCountChildren(Tree tree, unsigned int k) {
if (tree) {
Result leftResult = resultCountChildren(tree->left, k);
Result rightResult = resultCountChildren(tree->right, k);
unsigned int heightOfTree = 1 + max(leftResult.height, rightResult.height);
unsigned int count = leftResult.count + rightResult.count + (heightOfTree == k);
Result result = {
.height = heightOfTree,
.count = count
};
return result;
} else {
unsigned int height = 0;
unsigned int count = (0 == k);
Result result = {
.height = height,
.count = count
};
return result;
}
}
unsigned int count(Tree tree, unsigned int k) {
return resultCountChildren(tree).count;
}

Why am I getting a run-time error on school server but not on big servers like HackerEarth or HackerRank for this minimum spanning tree code?

I got a homework where I needed to wright a program to find MST of a graph. I tried running it on the school server but I get a run-time error. On big servers like HackerEarth or HackerRank, however, I got correct answers on all test cases. The boundary for the number of edges and vertices is 100000 and for the weight of an edge 10000. Vertices are labeled from 0 to n.
Here is my code:
#include <stdio.h>
#include <algorithm>
using namespace std;
class Edge
{
public:
int x, y;
long long w;
bool operator<(const Edge& next) const;
};
bool Edge::operator<(const Edge& next) const
{
return this->w < next.w;
}
class DisjointSet
{
public:
int parent, rank;
};
DisjointSet set[100100];
Edge edges[100100];
int findWithPathCompression(int x)
{
if(set[x].parent != x)
set[x].parent = findWithPathCompression(set[x].parent);
return set[x].parent;
}
bool unionByRank(int x1, int y1)
{
int x = findWithPathCompression(x1);
int y = findWithPathCompression(y1);
if(x == y)
return false;
if(set[x].rank > set[y].rank)
set[y].parent = x;
else if(set[y].rank > set[x].rank)
set[x].parent = y;
else
{
set[y].parent = x;
set[x].rank++;
}
return true;
}
int main()
{
int n, m, e = 0, c = 0;
long long r = 0;
scanf("%d %d",&n,&m);
for(int i = 0; i <= n; i++)
{
set[i].parent = i;
set[i].rank = 1;
}
for(int i = 0; i < m; i++)
{
scanf("%d %d %lld",&edges[i].x,&edges[i].y,&edges[i].w);
edges[i].x;
edges[i].y;
}
sort(edges,edges + m);
while(e != n - 1)
{
if(unionByRank(edges[c].x,edges[c].y))
{
r += edges[c].w;
e++;
}
c++;
}
printf("%lld\n",r);
}

Are there any example of Mutual recursion?

Are there any examples for a recursive function that calls an other function which calls the first one too ?
Example :
function1()
{
//do something
function2();
//do something
}
function2()
{
//do something
function1();
//do something
}
Mutual recursion is common in code that parses mathematical expressions (and other grammars). A recursive descent parser based on the grammar below will naturally contain mutual recursion: expression-terms-term-factor-primary-expression.
expression
+ terms
- terms
terms
terms
term + terms
term - terms
term
factor
factor * term
factor / term
factor
primary
primary ^ factor
primary
( expression )
number
name
name ( expression )
The proper term for this is Mutual Recursion.
http://en.wikipedia.org/wiki/Mutual_recursion
There's an example on that page, I'll reproduce here in Java:
boolean even( int number )
{
if( number == 0 )
return true;
else
return odd(abs(number)-1)
}
boolean odd( int number )
{
if( number == 0 )
return false;
else
return even(abs(number)-1);
}
Where abs( n ) means return the absolute value of a number.
Clearly this is not efficient, just to demonstrate a point.
An example might be the minmax algorithm commonly used in game programs such as chess. Starting at the top of the game tree, the goal is to find the maximum value of all the nodes at the level below, whose values are defined as the minimum of the values of the nodes below that, whose values are defines as the maximum of the values below that, whose values ...
I can think of two common sources of mutual recursion.
Functions dealing with mutually recursive types
Consider an Abstract Syntax Tree (AST) that keeps position information in every node. The type might look like this:
type Expr =
| Int of int
| Var of string
| Add of ExprAux * ExprAux
and ExprAux = Expr of int * Expr
The easiest way to write functions that manipulate values of these types is to write mutually recursive functions. For example, a function to find the set of free variables:
let rec freeVariables = function
| Int n -> Set.empty
| Var x -> Set.singleton x
| Add(f, g) -> Set.union (freeVariablesAux f) (freeVariablesAux g)
and freeVariablesAux (Expr(loc, e)) =
freeVariables e
State machines
Consider a state machine that is either on, off or paused with instructions to start, stop, pause and resume (F# code):
type Instruction = Start | Stop | Pause | Resume
The state machine might be written as mutually recursive functions with one function for each state:
type State = State of (Instruction -> State)
let rec isOff = function
| Start -> State isOn
| _ -> State isOff
and isOn = function
| Stop -> State isOff
| Pause -> State isPaused
| _ -> State isOn
and isPaused = function
| Stop -> State isOff
| Resume -> State isOn
| _ -> State isPaused
It's a bit contrived and not very efficient, but you could do this with a function to calculate Fibbonacci numbers as in:
fib2(n) { return fib(n-2); }
fib1(n) { return fib(n-1); }
fib(n)
{
if (n>1)
return fib1(n) + fib2(n);
else
return 1;
}
In this case its efficiency can be dramatically enhanced if the language supports memoization
In a language with proper tail calls, Mutual Tail Recursion is a very natural way of implementing automata.
Here is my coded solution. For a calculator app that performs *,/,- operations using mutual recursion. It also checks for brackets (()) to decide the order of precedence.
Flow:: expression -> term -> factor -> expression
Calculator.h
#ifndef CALCULATOR_H_
#define CALCULATOR_H_
#include <string>
using namespace std;
/****** A Calculator Class holding expression, term, factor ********/
class Calculator
{
public:
/**Default Constructor*/
Calculator();
/** Parameterized Constructor common for all exception
* #aparam e exception value
* */
Calculator(char e);
/**
* Function to start computation
* #param input - input expression*/
void start(string input);
/**
* Evaluates Term*
* #param input string for term*/
double term(string& input);
/* Evaluates factor*
* #param input string for factor*/
double factor(string& input);
/* Evaluates Expression*
* #param input string for expression*/
double expression(string& input);
/* Evaluates number*
* #param input string for number*/
string number(string n);
/**
* Prints calculates value of the expression
* */
void print();
/**
* Converts char to double
* #param c input char
* */
double charTONum(const char* c);
/**
* Get error
*/
char get_value() const;
/** Reset all values*/
void reset();
private:
int lock;//set lock to check extra parenthesis
double result;// result
char error_msg;// error message
};
/**Error for unexpected string operation*/
class Unexpected_error:public Calculator
{
public:
Unexpected_error(char e):Calculator(e){};
};
/**Error for missing parenthesis*/
class Missing_parenthesis:public Calculator
{
public:
Missing_parenthesis(char e):Calculator(e){};
};
/**Error if divide by zeros*/
class DivideByZero:public Calculator{
public:
DivideByZero():Calculator(){};
};
#endif
===============================================================================
Calculator.cpp
//============================================================================
// Name : Calculator.cpp
// Author : Anurag
// Version :
// Copyright : Your copyright notice
// Description : Calculator using mutual recursion in C++, Ansi-style
//============================================================================
#include "Calculator.h"
#include <iostream>
#include <string>
#include <math.h>
#include <exception>
using namespace std;
Calculator::Calculator():lock(0),result(0),error_msg(' '){
}
Calculator::Calculator(char e):result(0), error_msg(e) {
}
char Calculator::get_value() const {
return this->error_msg;
}
void Calculator::start(string input) {
try{
result = expression(input);
print();
}catch (Unexpected_error e) {
cout<<result<<endl;
cout<<"***** Unexpected "<<e.get_value()<<endl;
}catch (Missing_parenthesis e) {
cout<<"***** Missing "<<e.get_value()<<endl;
}catch (DivideByZero e) {
cout<<"***** Division By Zero" << endl;
}
}
double Calculator::expression(string& input) {
double expression=0;
if(input.size()==0)
return 0;
expression = term(input);
if(input[0] == ' ')
input = input.substr(1);
if(input[0] == '+') {
input = input.substr(1);
expression += term(input);
}
else if(input[0] == '-') {
input = input.substr(1);
expression -= term(input);
}
if(input[0] == '%'){
result = expression;
throw Unexpected_error(input[0]);
}
if(input[0]==')' && lock<=0 )
throw Missing_parenthesis(')');
return expression;
}
double Calculator::term(string& input) {
if(input.size()==0)
return 1;
double term=1;
term = factor(input);
if(input[0] == ' ')
input = input.substr(1);
if(input[0] == '*') {
input = input.substr(1);
term = term * factor(input);
}
else if(input[0] == '/') {
input = input.substr(1);
double den = factor(input);
if(den==0) {
throw DivideByZero();
}
term = term / den;
}
return term;
}
double Calculator::factor(string& input) {
double factor=0;
if(input[0] == ' ') {
input = input.substr(1);
}
if(input[0] == '(') {
lock++;
input = input.substr(1);
factor = expression(input);
if(input[0]==')') {
lock--;
input = input.substr(1);
return factor;
}else{
throw Missing_parenthesis(')');
}
}
else if (input[0]>='0' && input[0]<='9'){
string nums = input.substr(0,1) + number(input.substr(1));
input = input.substr(nums.size());
return stod(nums);
}
else {
result = factor;
throw Unexpected_error(input[0]);
}
return factor;
}
string Calculator::number(string input) {
if(input.substr(0,2)=="E+" || input.substr(0,2)=="E-" || input.substr(0,2)=="e-" || input.substr(0,2)=="e-")
return input.substr(0,2) + number(input.substr(2));
else if((input[0]>='0' && input[0]<='9') || (input[0]=='.'))
return input.substr(0,1) + number(input.substr(1));
else
return "";
}
void Calculator::print() {
cout << result << endl;
}
void Calculator::reset(){
this->lock=0;
this->result=0;
}
int main() {
Calculator* cal = new Calculator;
string input;
cout<<"Expression? ";
getline(cin,input);
while(input!="."){
cal->start(input.substr(0,input.size()-2));
cout<<"Expression? ";
cal->reset();
getline(cin,input);
}
cout << "Done!" << endl;
return 0;
}
==============================================================
Sample input-> Expression? (42+8)*10 =
Output-> 500
Top down merge sort can use a pair of mutually recursive functions to alternate the direction of merge based on level of recursion.
For the example code below, a[] is the array to be sorted, b[] is a temporary working array. For a naive implementation of merge sort, each merge operation copies data from a[] to b[], then merges b[] back to a[], or it merges from a[] to b[], then copies from b[] back to a[]. This requires n · ceiling(log2(n)) copy operations. To eliminate the copy operations used for merging, the direction of merge can be alternated based on level of recursion, merge from a[] to b[], merge from b[] to a[], ..., and switch to in place insertion sort for small runs in a[], as insertion sort on small runs is faster than merge sort.
In this example, MergeSortAtoA() and MergeSortAtoB() are the mutually recursive functions.
Example java code:
static final int ISZ = 64; // use insertion sort if size <= ISZ
static void MergeSort(int a[])
{
int n = a.length;
if(n < 2)
return;
int [] b = new int[n];
MergeSortAtoA(a, b, 0, n);
}
static void MergeSortAtoA(int a[], int b[], int ll, int ee)
{
if ((ee - ll) <= ISZ){ // use insertion sort on small runs
InsertionSort(a, ll, ee);
return;
}
int rr = (ll + ee)>>1; // midpoint, start of right half
MergeSortAtoB(a, b, ll, rr);
MergeSortAtoB(a, b, rr, ee);
Merge(b, a, ll, rr, ee); // merge b to a
}
static void MergeSortAtoB(int a[], int b[], int ll, int ee)
{
int rr = (ll + ee)>>1; // midpoint, start of right half
MergeSortAtoA(a, b, ll, rr);
MergeSortAtoA(a, b, rr, ee);
Merge(a, b, ll, rr, ee); // merge a to b
}
static void Merge(int a[], int b[], int ll, int rr, int ee)
{
int o = ll; // b[] index
int l = ll; // a[] left index
int r = rr; // a[] right index
while(true){ // merge data
if(a[l] <= a[r]){ // if a[l] <= a[r]
b[o++] = a[l++]; // copy a[l]
if(l < rr) // if not end of left run
continue; // continue (back to while)
while(r < ee){ // else copy rest of right run
b[o++] = a[r++];
}
break; // and return
} else { // else a[l] > a[r]
b[o++] = a[r++]; // copy a[r]
if(r < ee) // if not end of right run
continue; // continue (back to while)
while(l < rr){ // else copy rest of left run
b[o++] = a[l++];
}
break; // and return
}
}
}
static void InsertionSort(int a[], int ll, int ee)
{
int i, j;
int t;
for (j = ll + 1; j < ee; j++) {
t = a[j];
i = j-1;
while(i >= ll && a[i] > t){
a[i+1] = a[i];
i--;
}
a[i+1] = t;
}
}

Resources