I have an array suppose {10,1,10,9}
Now I have to a form a binary tree with start node as array[0] which is 10 here, the tree structure will be like this
first element 10
here in the picture, first element is 10, now I have to select left child and right child, so 2nd element is my left child and last element is my right child.
If 1 is my left child then I am having 10 and 9 remaining to process so 10 will be left child and 9 will be the right child for 1 as parent, now for 10 as parent, only 9 is left, so this would be the left child, and so one this tree is building.
I am trying to use recursion which I am little weak and trying to learn,but my code is not working how I am thinking, obviously I am doing somthing wrong, please guide me through this.
#include<iostream>
using namespace std;
int temparr[20];
void calculateMax(int arr[],int start, int end)
{
if(start > end)
return;
cout<<arr[start]<<" ";
calculateMax(arr,start+1,end);
calculateMax(arr,start,end-1);
}
int main()
{
int arr[] = {10,1,10,9};
temparr[0] = 10;
int n = sizeof(arr)/sizeof(int);
calculateMax(arr,0,n-1);
//for(int i=0;i<20;++i)
//cout<<temparr[i]<<" ";
return 0;
}
my cout should output 10 1 10 9 9 10 9 1 10 10 1 but its not.
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
A complete binary tree with a maximum depth of 16 is known, with all leaf nodes having the same depth. If a small ball is placed at the root node, the ball will begin to fall along the root node. There is a switch on each node in the complete binary tree. The default is all off. When the ball falls, the state of the switch changes whenever a ball falls on a switch. When the ball reaches a node, if the switch on the node is closed, go to the left to go to the ball, otherwise go to the right until it reaches the leaf node. Please help me find the leaf node number after the 12345th ball fell.
You can simulate the given problem and notice that the leaf node at which the ball ends tends to repeat itself after a point of time. For example, for a binary tree of depth 3, the leaf nodes at which the ball ends for multiple roll of the balls are 1 3 2 4 1 3 2 4 1 3 2 4 . . . (assuming the leaf nodes are numbered starting from 1). As visible, the sequence of length 23-1 = 4 keeps repeating itself. We can store this sequence in an array and answer the query for any nth ball throw by looking up the entry corresponding to the n mod 2depth-1 index in this array.
Since our depth is upto 16, the total number of operations required to generate the recurring sequence is 216-1 * 16 = 524288 operations.
Sharing the code for the same https://ideone.com/uuNV2g
#include <iostream>
#include <map>
#include <vector>
using namespace std;
map<int, bool> states; // default value is False
int MAX_DEPTH = 16;
int dfs(int cur, int depth = 0) {
if(depth == MAX_DEPTH) {
return cur - (1<<MAX_DEPTH) + 1;
}
if(states[cur] == 0) {
states[cur] = !states[cur];
return dfs(2*cur, depth+1);
}
else {
states[cur] = !states[cur];
return dfs(2*cur+1, depth+1);
}
}
int main() {
int until = (1LL<<(MAX_DEPTH-1));
vector<int> pos; // 0 indexed
for(int i = 1; i <= until; i++) {
// cout << dfs(1) << ' ';
pos.push_back(dfs(1));
}
cout << pos[(12344%until)];
// 12344 instead of 12345 since the sequence is 0 indexed
}
Hope it works out.
Suppose I have a binary search tree in which I'm supposed to insert N unique-numbered keys in the order given to me on standard input, then I am to delete all nodes with keys in interval I = [min,max] and also all connections adjacent to these nodes. This gives me a lot of smaller trees that I am to merge together in a particular way. More precise description of the problem:
Given a BST, which contains distinct keys, and interval I, the interval deletion works in two phases. During the first phase it removes all nodes whose key is in I and all edges adjacent to the removed nodes. Let the resulting graph contain k connected components T1,...,Tk. Each of the components is a BST where the root is the node with the smallest depth among all nodes of this component in the original BST. We assume that the sequence of trees Ti is sorted so that for each i < j all keys in Ti are smaller than keys in Tj. During the second phase, trees Ti are merged together to form one BST. We denote this operation by Merge(T1,...,Tk). Its output is defined recurrently as follows:
EDIT: I am also supposed to delete any edge that connects nodes, that are separated by the given interval, meaning in example 2 the edge connecting nodes 10 and 20 is deleted because the interval[13,15] is 'in between them' thus separating them.
For an empty sequence of trees, Merge() gives an empty BST.
For a one-element sequence containing a tree T, Merge(T) = T.
For a sequence of trees T1,...,Tk where k > 1, let A1< A2< ... < An be the sequence of keys stored in the union of all trees T1,...,Tk, sorted in ascending order. Moreover, let m = ⌊(1+k)/2⌋ and let Ts be the tree which contains Am. Then, Merge(T1,...,Tk) gives a tree T created by merging three trees Ts, TL = Merge(T1,...,Ts-1) and TR = Merge(Ts+1,...,Tk). These trees are merged by establishing the following two links: TL is appended as the left subtree of the node storing the minimal key of Ts and TR is appended as the right subtree of the node storing the maximal key of Ts.
After I do this my task is to find the depth D of the resulting merged tree and the number of nodes in depth D-1. My program should be finished in few seconds even for a tree of 100000s of nodes (4th example).
My problem is that I haven't got a clue on how to do this or where even start. I managed to construct the desired tree before deletion but that's about that.
I'd be grateful for implementation of a program to solve this or any advice at all. Preferably in some C-ish programming language.
examples:
input(first number is number of keys to be inserted in the empty tree, the second are the unique keys to be inserted in the order given, the third line containts two numbers meaning the interval to be deleted):
13
10 5 8 6 9 7 20 15 22 13 17 16 18
8 16
correct output of the program: 3 3 , first number being the depth D, the second number of nodes in depth D-1
input:
13
10 5 8 6 9 7 20 15 22 13 17 16 18
13 15
correct output: 4 3
pictures of the two examples
example 3: https://justpaste.it/1du6l
correct output: 13 6
example 4: link
correct output: 58 9
This is a big answer, I'll talk at high-level.Please examine the source for details, or ask in comment for clarification.
Global Variables :
vector<Node*> roots : To store roots of all new trees.
map<Node*,int> smap : for each new tree, stores it's size
vector<int> prefix : prefix sum of roots vector, for easy binary search in merge
Functions:
inorder : find size of a BST (all calls combinedly O(N))
delInterval : Main theme is,if root isn't within interval, both of it's childs might be roots of new trees. The last two if checks for that special edge in your edit. Do this for every node, post-order. (O(N))
merge : Merge all new roots positioned at start to end index in roots. First we find the total members of new tree in total (using prefix-sum of roots i.e prefix). mid denotes m in your question. ind is the index of root that contains mid-th node, we retrieve that in root variable. Now recursively build left/right subtree and add them in left/right most node. O(N) complexity.
traverse: in level map, compute the number of nodes for every depth of tree. (O(N.logN), unordered_map will turn it O(N))
Now the code (Don't panic!!!):
#include <bits/stdc++.h>
using namespace std;
int N = 12;
struct Node
{
Node* parent=NULL,*left=NULL,*right = NULL;
int value;
Node(int x,Node* par=NULL) {value = x;parent = par;}
};
void insert(Node* root,int x){
if(x<root->value){
if(root->left) insert(root->left,x);
else root->left = new Node(x,root);
}
else{
if(root->right) insert(root->right,x);
else root->right = new Node(x,root);
}
}
int inorder(Node* root){
if(root==NULL) return 0;
int l = inorder(root->left);
return l+1+inorder(root->right);
}
vector<Node*> roots;
map<Node*,int> smap;
vector<int> prefix;
Node* delInterval(Node* root,int x,int y){
if(root==NULL) return NULL;
root->left = delInterval(root->left,x,y);
root->right = delInterval(root->right,x,y);
if(root->value<=y && root->value>=x){
if(root->left) roots.push_back(root->left);
if(root->right) roots.push_back(root->right);
return NULL;
}
if(root->value<x && root->right && root->right->value>y) {
roots.push_back(root->right);
root->right = NULL;
}
if(root->value>y && root->left && root->left->value<x) {
roots.push_back(root->left);
root->left = NULL;
}
return root;
}
Node* merge(int start,int end){
if(start>end) return NULL;
if(start==end) return roots[start];
int total = prefix[end] - (start>0?prefix[start-1]:0);//make sure u get this line
int mid = (total+1)/2 + (start>0?prefix[start-1]:0); //or this won't make sense
int ind = lower_bound(prefix.begin(),prefix.end(),mid) - prefix.begin();
Node* root = roots[ind];
Node* TL = merge(start,ind-1);
Node* TR = merge(ind+1,end);
Node* temp = root;
while(temp->left) temp = temp->left;
temp->left = TL;
temp = root;
while(temp->right) temp = temp->right;
temp->right = TR;
return root;
}
void traverse(Node* root,int depth,map<int, int>& level){
if(!root) return;
level[depth]++;
traverse(root->left,depth+1,level);
traverse(root->right,depth+1,level);
}
int main(){
srand(time(NULL));
cin>>N;
int* arr = new int[N],start,end;
for(int i=0;i<N;i++) cin>>arr[i];
cin>>start>>end;
Node* tree = new Node(arr[0]); //Building initial tree
for(int i=1;i<N;i++) {insert(tree,arr[i]);}
Node* x = delInterval(tree,start,end); //deleting the interval
if(x) roots.push_back(x);
//sort the disconnected roots, and find their size
sort(roots.begin(),roots.end(),[](Node* r,Node* v){return r->value<v->value;});
for(auto& r:roots) {smap[r] = inorder(r);}
prefix.resize(roots.size()); //prefix sum root sizes, to cheaply find 'root' in merge
prefix[0] = smap[roots[0]];
for(int i=1;i<roots.size();i++) prefix[i]= smap[roots[i]]+prefix[i-1];
Node* root = merge(0,roots.size()-1); //merge all trees
map<int, int> level; //key=depth, value = no of nodes in depth
traverse(root,0,level); //find number of nodes in each depth
int depth = level.rbegin()->first; //access last element's key i.e total depth
int at_depth_1 = level[depth-1]; //no of nodes before
cout<<depth<<" "<<at_depth_1<<endl; //hoorray
return 0;
}
#include <iostream>
#include <vector>
#include <stack>
using namespace std;
class Graph{
public:
vector<int> adjList[10001];
void addEdge(int u,int v){
adjList[u].push_back(v);
adjList[v].push_back(u);
}
};
bool dfs(Graph graph, int n){
vector<int> neighbors;
int curr,parent;
bool visited[10001] = {0};
stack<int> s;
//Depth First Search
s.push(1);
parent = 0;
while(!s.empty()){
curr = s.top();
neighbors = graph.adjList[curr];
s.pop();
//If current is unvisited
if(visited[curr] == false){
for(int j=0; j<neighbors.size(); j++){
//If node connected to itself, then cycle exists
if(neighbors[j] == curr){
return false;;
}
else if(visited[neighbors[j]] == false){
s.push(neighbors[j]);
}
//If the neighbor is already visited, and it is not a parent, then cycle is detected
else if(visited[neighbors[j]] == true && neighbors[j] != parent){
return false;
}
}
//Mark as visited
visited[curr] = true;
parent = curr;
}
}
//Checking if graph is fully connected
for(int i=1; i<=n; i++){
if(visited[i] == false){
return false;
}
}
//Only if there are no cycles, and it's fully connected, it's a tree
return true;
}
int main() {
int m,n,u,v;
cin>>n>>m;
Graph graph = Graph();
//Build the graph
for(int edge=0; edge<m; edge++){
cin>>u>>v;
graph.addEdge(u,v);
}
if(dfs(graph,n)){
cout<<"YES"<<endl;
}
else{
cout<<"NO"<<endl;
}
return 0;
}
I am trying to determine if a given graph is a tree.
I perform DFS and look for cycles, if a cycle is detected, then the given graph is not a tree.
Then I check if all nodes have been visited, if any node is not visited, then given graph is not a tree
The first line of input is:
n m
Then m lines follow, which represent the edges connecting two nodes
n is number of nodes
m is number of edges
example input:
3 2
1 2
2 3
This is a SPOJ question http://www.spoj.com/problems/PT07Y/ and I am getting Wrong Answer. But the DFS seems to be correct according to me.
So I checked your code against some simple test cases in comments, and it seems that for
7 6
3 1
3 2
2 4
2 5
1 6
1 7
you should get YES as answer, while your program gives NO.
This is how neighbours looks like in this case:
1: 3 6 7
2: 3 4 5
3: 1 2
4: 2
5: 2
6: 1
7: 1
So when you visit 1 you push 3,6,7 on the stack. Your parent is set as 1. This is all going good.
You pop 7 from the stack, you don't push anything on the stack and cycle check clears out, so as you exit while loop you set visited[7] as true and set you parent to 7 (!!!!!).
Here is you can see this is not going well, since once you popped 6 from the stack you have 7 saved as parent. And it should be 1. This makes cycle check fail on neighbor[0] != parent.
I'd suggest adding keeping parent in mapped array and detect cycles by applying union-merge.
I had a test right now and this was one of the questions:
Input
The places to visit in the labyrinth are numbered from 1 to n. The entry and
the exit correspond to number 1 and number n, respectively; the remaining
numbers correspond to crossings. Note that there are no dead ends and
there is no more than one connection linking a pair of crossings.
For each test case, the first line gives n and the number of connections
between crossings (m). Then, in each of the following m lines, you find a pair
of integers corresponding to the connection between two crossings.
Output
For each test case, your implementation should output one single line
containing "Found!", if it is possible to reach the exit by visiting every
crossing once or "Damn!", otherwise. Other test cases may follow.
Constraints
m < 32
n < 21
Example input:
8 13
1 2
1 3
2 3
2 4
3 4
3 5
4 5
4 6
5 6
5 7
6 7
6 8
7 8
8 8
1 2
1 3
2 4
3 5
4 6
5 7
6 8
7 8
Example output:
Found!
Damn!
I solved the problem using a sort of DFS algorithm but i have a few questions.
Using DFS algorithm, I implemented a recursive function that starts in the given node and tries to visit every node once and the last node must be the exit node. I don't have the full code right now but but it was something like this:
findPath(int current node, int numVisitedNodes, int *visited){
int *tmpVisited = copyArray(visited); //copies the visited array to tmpVisited
//DFS algo here
}
Every recursive call it copies the visited nodes array. I'm doing this because when it finds an invalid path and the recursion goes back to the origin, it can still go because no one overwrote the visited nodes list.
Is there any better way to do this?
How would you solve it? (you can provide code if you want)
Read the crossing
if start or end of the crossing belongs to a reachable set, add both to that set else create a new reachable set.
When input has finished, check if any of the reachable sets contains
both entrance and exit points
HashSet operations complexity is O(1). If every crossing are distinct, complexity is O(n^2),which is the worst case complexity of this algorithm. Space complexity is O(n), there is no recursion so there is no recursion overhead of memory.
Roughly speaking, every node is visited only once.
Java code using valid reachable sets is as follows.
public class ZeManel {
public static void main(String[] args) {
Integer[][] input = {{1,2},{2,3},{4,6}};
zeManel(input);
}
public static void zeManel(Integer[][] input){
List<Set<Integer>> paths = new ArrayList<Set<Integer>>();
int max = 0;
for(int i = 0;i < input.length;i++) {
max = input[i][0] > max ? input[i][0] : max;
max = input[i][1] > max ? input[i][1] : max;
boolean inPaths = false;
for (Set<Integer> set : paths) {
if(set.contains(input[i][0]) || set.contains(input[i][1])) {
set.add(input[i][0]);
set.add(input[i][1]);
inPaths = true;
break;
}
}
if(!inPaths) {
Set<Integer> path = new HashSet<Integer>();
path.add(input[i][0]);
path.add(input[i][1]);
paths.add(path);
}
}
for (Set<Integer> path : paths) {
if(path.contains(1) && path.contains(max)) {
System.out.println("Found!");
return;
}
}
System.out.println("Damn!");
}
}
This was my implementation during the test:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
# define N 21
# define M 32
int i;
int adj[N][N];
int count = 0;
int findPath(int numNodes, int currentNode, int depth, int *visited){
visited[currentNode] = 1;
if(currentNode == numNodes - 1 && depth == numNodes){
return 1;
}
if(depth > numNodes)
return -1;
int r = -1;
if(depth < numNodes){
count++;
int *tmp = (int*) malloc(numNodes*sizeof(int));
for(i = 0; i < numNodes; i++)
tmp[i] = visited[i];
for(i = 0; i < numNodes; i++){
if(adj[currentNode][i] == 1 && tmp[i] == 0 && r == -1){
if(findPath(numNodes, i, depth + 1, tmp) == 1)
r = 1;
}
}
free(tmp);
}
return r;
}
int main(){
int numLigacoes, a, b, numNodes;
int *visited;
while (scanf("%d %d", &numNodes, &numLigacoes) != EOF){
visited = (int*) malloc(numNodes*sizeof(int));
count = 0;
memset(adj, 0, N*N*sizeof(int));
memset(visited, 0, numNodes*sizeof(int));
for (i = 0; i < numLigacoes; i++){
scanf("%d %d", &a, &b);
adj[a - 1][b - 1] = 1;
adj[b - 1][a - 1] = 1;
}
if(findPath(numNodes, 0, 1, visited) == 1)
printf("Found! (%d)\n", count);
else
printf("Damn! (%d)\n", count);
free(visited);
}
return 0;
}
What do you think about that?
This was asked to me in an interview which I screwed up. We are given a binary tree , however , it is modified such that it's children are never null , if a non leaf node doesn't have a child then its right/left child points to the node itself. And for the leaf nodes , they point to the next left node and right node. For leftmost and rightmost node it will be pointing to itself and the previous/next element.
Example :
1
/ \
2 3
/ \ / \
(4 = 5 = 6 = 7)
Here 4.left = 4 , 4.right = 5 , 5.left = 4 and 5.right = 6 and so on.
We need to do an inorder traversal of this tree.
I came up with the conditions which will determine if a node is leaf node (exit condition):
if(root.right==root || root.left == root || root.left.right == root || root.right.left == root)
But couldn't combine these properly. Also we need to take care of skewed trees for which even the root satifies the condition root.left = root || root.right = right , so we will straight away get out of recursion without even traversing the whole tree.
Please help me with it. I couldn't come up with proper condition check for recursion.
We just need to do an in order traversal of this tree. Output : 4 2 5 1 6 3 7
The following algorithm should do:
visit(vertex v) {
if (v.left != v && v.left.right != v) visit(v.left)
print v
if (v.right != v && v.right.left != v) visit(v.right)
}
I think your problem was that you tried to do too many things at a time. Instead of detecting whether the vertex is a leaf or not, it would have sufficed to detect first whether it has a left child and then whether it has a right child.
If you hit a non-leaf that points to itself on the right side, but has a child on the left side, a condition like 'root.right==root' would falsely call that node a leaf. You need to use an and statement. I think this might work:
if((root.right==root && root.left.right == root) || (root.left == root && root.right.left == root) || (root.left.right == root && root.left == root))
But this will not work if you have a tree with a missing leaf in the middle. Of course if the nodes were numbered, then it would be much easier since you could just use log2 to check what level it was on compared to where it linked to.
For clarity, I put all the bizarre logic into a function (which could be inlined)
#include <stdio.h>
struct list {
struct list *prev;
struct list *next;
int val;
};
struct list arr[] =
{ {arr+1, arr+2, 1}
, {arr+3, arr+4, 2}
, {arr+5, arr+6, 3}
, {arr+3, arr+4, 4}
, {arr+3, arr+5, 5}
, {arr+4, arr+6, 6}
, {arr+5, arr+6, 7}
};
int is_leaf(struct list *p)
{
if (p->prev == p) return 1; // 4
if (p->next == p) return 1; // 7
if (p->next->prev == p) return 1; // 5,6
return 0; // non-leaves : 1,2,3
}
unsigned recurse (struct list *p)
{
int chk;
unsigned ret=1;
chk = is_leaf(p) ;
if (!chk) ret+=recurse(p->prev);
printf("%d %s\n", p->val, chk ? "leaf" : "nonLeaf" );
if (!chk) ret+=recurse(p->next);
return ret;
}
int main (void) {
unsigned cnt;
cnt = recurse (arr);
printf( "Result=%u\n", cnt );
return 0;
}
Output:
4 leaf
2 nonLeaf
5 leaf
1 nonLeaf
6 leaf
3 nonLeaf
7 leaf
Result=7