Oracle Interview Question for Member Technical Staffs


Country: India
Interview Type: In-Person




Comment hidden because of low score. Click to expand.
2
of 2 vote

I am considering default implementation of Binary tree. Parent node is not given.
Using an extra class:

Pair {
		Node node;
		int distance; // To get upwards distance from given node = (depth - distance) .
	}
Step 1. int depth = 0; // After this step it will hold depth of node.
Start from root and traverse path from root to given node (source node), and create a object of Pair(parentNode, depth++)) and add it in a Queue of size K.
If Queue is full before reaching the node (because depth can be larger than K) than remove one node from rear to make space and new node at front.

After this step Queue will hold all nodes and distance upwards at K or less distance from given node.

Queue result; //This will be output.
Step 2: Now find all upward nodes.
     while (Queue ! = NULL){
	 Pair pair  = parentQueue.dequeue();
	 int i = depth - pair.diatance;
	 if( i = K){
             result.add(pair.node);
	 }
         perfrom findKthNodesDownwards(givenNode, pair.node, K - i)
       }

Step 3: Find all downward nodes.
	findKthNodesDownwards(givenNode, null, K)



void findKthNodesDownwards(Node givenNode, Node node , int k)    
{
   if(node == NULL || givenNode == node) 
      return;
   if( k == 0 )
   {
      nodes.add(node);
      return ;
   }
   else
   {      
      findKthNodes( node.left, k-1 ) ;
      findKthNodes( root.right, k-1 ) ;
   }
}

- Ajeet October 20, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
1
of 1 vote

parent pointers available ?

- Teapot October 19, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
1
of 1 vote

store tree as graph and find the distance from the node to other nodes using graph algorithm.

- vikas October 20, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

mark every node as a binary number,

root -> 1
left node to root -> 10
right node to root -> 11
after that -> 100-101 and 110-111

.. and so on, we will have a tree of binary numbers.

now suppose we want to know distance between '100' and '1011', follow these steps,

1. '100' would be at 'level 2' and '1011' at 'level 3'. Parent of '1011' would be '101' and it's distance '1011' would be '1'. We now have to fine distance between 100 and 101.

2. XOR '100' and '101' => '001'. Position of left most '1' in '001' gives distance of common ancestor. In this case it is '1'.

3. Distance between 100 and 1011 would be 2 * 'common ancestor distance' + ( 1011 <-> 101 distance). which is 2*1 + 1 = 3

So 3 is the distance. This way we can calculate all the distances.

- deepak.bvp October 20, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Is that the approach you would use to find the neighbors of a node, i.e. for k = 1?

The number of nodes at distance k is number of neighbors of nodes at distance k-1.
And so on, recursively.

- Anonymous October 20, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Sounds cool.
Pseudocode?

- S O U N D W A V E October 22, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

// generates a similar tree with corresponding binary positions
// binary positions are like '101' or '1011' etc
$positionsTreeRoot = formBinaryPositionTree($root);

method getNeighbours($tempRoot,$node, $k){
	//getBinaryPosition returns binaryPositons from $positionsTreeRoot
	$nodeBinaryPosition = getBinaryPosition($node);
	$rootBinaryPosition = getBinaryPosition($tempRoot);
	if(     getDistance(
                               $nodeBinaryPosition, 
                               $rootBinaryPosition
                                   ) == $k    )
		print $tempRoot->data
	//continue traversal
	if($tempRoot->left != NULL)
		getNeighbours($tempRoot->left,$node, $k);
	if($tempRoot->right != NULL)
		getNeighbours($tempRoot->right,$node, $k);
}

/*
$position1 and $position2 are binary 
*/
method getDistance($position1, $position2){
	//binLength returns length ie, 101 > 3, 1011 > 4
	$binLenDiff = binLength($position1) -  binLength($position2);
	if($binLenDiff < 0)
           shift right $position2 abs($binLenDiff) times	
       else
           shift right $position1 abs($binLenDiff) times
 	//now position1 and position2 are of equal length	
       $xor = $position1 ^ $position2;
       return ( 2* BinLength($xor)) + abs($binLenDiff);
}

- deepak.bvp October 23, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

here's the pseudo code of an approach I can think of:

void getAllNodesAtk(node *q, int k, <the list of nodes so far> l {
if(q == NULL) {
return;
}

if(k == 0) {
l union {q} and return;
}

getAllNodesAtk(q->left, k-1, l)
getAllNodesAtk(q->right, k-1, l)
}

- Anonymous October 20, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

2 times 2 variations == 4 combinations exist for this problem.

2 choices
========
You can be given a key (must find the node) or given reference to the node (can access the node in question directly).

2 choices
========
Parent pointers available or not.


What does the original poster want code for?

- S O U N D W A V E October 22, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Here is my idea for "no parent pointers"
(I would search for the Node first regardless of key vs. node ref.)"

//without parent pointers (similar if you are searching for a target key)
find_kth(Node x, Node target, k)
{
    if( x == nil ) return INF;  //treat it like infinity in remaining stuff  
    
    if( x == target ) {  
        DFS_down(x, k);
        return 0;           //0 hops above target node 
    }
    //calculate number of hops away from target node
    int away= MIN( find_kth(x.left, target, k), find_kth(x.right, target, k) ) + 1;

    if( away<= k ) DFS_down(x, k-away);  //DFS down if hops to spare
    
    return away;  
}

DFS_down(Node x, k)
{
    if( x == nil ) return; 
    if( k == 0 ) { cout << x or x.val << " is found as desired"; return; }
    
    DFS_down(x.right, k-1); DFS_down(x.left, k-1);
}

I tend to think of pseudocode with infinity or other sentinels (to shorten required thinking) so left it in there (my style). Fix the bugs as you desire.

Drawing a tree (not a symmetric perfect case) on paper (or your mind) makes almost all tree questions very tractable.

- S O U N D W A V E October 22, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

This should cover the two other combinations (i.e, "with parent pointers"):

//with parent pointers and given key to find (must search for Node)
find_kth(Node x, Key val, k)
{
    if( x == nil ) return;  
    
    if( x.val == val ) {  //at Node x, DFS down for k-th distance nodes
        DFS(x, nil, k);
        return 0;        //current node is "0" links above target node 
    }
    find_kth(x.right, val, k);
    find_kth(x.left, val, k);
}

//called by above OR called directly in the "Parent Pointers + Node Ref." case;
DFS(Node x, Node prev, k)
{
    if( x == nil ) return; 
    if( k == 0 ) { cout << x << " is one such Node" << endl; return; }
    
    if( x.right != prev)    DFS(x.right, x, k-1);
    if( x.left != prev)      DFS(x.left, x, k-1);
    if( x.parent != prev) DFS(x.parent, x, k-1); 
}

With a macro, we can hide some of the ugliness in the last part above
( C/C++/pseudocde style marcos)

#define safeDFS(t) if( x.t != prev ) {DFS(x.t, x, k-1);}

DFS(Node x, Node prev, k)
{
    if( x == nil ) return; 
    if( k == 0 ) { cout << x << " is one such Node" << endl; return; }
    
    safeDFS(right);
    safeDFS(left);
    safeDFS(parent); 
}

- S O U N D W A V E October 22, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Thanks to Archit Thawaria for finding a case that broke the no parent pointer code :)
In fact, we need to track 'prev' even for no-parent pointer cases (only for a small part of downward DFS)

/* collabedit.com/w57qp for further updates, anyone can do it */

//without parent pointers (similar if you are searching for a target key)
find_kth(Node x, Node target, k, *prev)  <= better to have a wrapper
{
    if( x == nil ) return INF;  //treat it like infinity in remaining stuff  
    
    if( x == target ) {  
        DFS_down(x, k);
        *prev=target;   //set prev node as target node
        return 0;       //0 hops above target node 
    }
    //calculate number of hops away from target node
    int away1 = find_kth(x.left, target, k, &prev1); 
    int away2 = find_kth(x.right, target, k, &prev2);
    
    if( away1 < INF ) prev = prev1, away=away1;
    elif( away2 < INF ) prev = prev2, away=away2;  

    if( ++away <= k ) DFS_down(x, k-away, prev);  //DFS down if hops to spare
    
    *prev=x;  //set prev. node as current node
    return away;  
}

DFS_down(Node x, Node *prev, k) //prev!=nil => dont BFS down there
{
    if( x == nil ) return; 
    if( k == 0 ) { cout << x or x.val << " is found as desired"; return; }
    
    if(x.right != *prev) DFS_down(x.right, nil, k-1);
    if(x.left != *prev)  DFS_down(x.left, nil, k-1);  //remaining dont need prev
}

- S O U N D W A V E October 22, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

#include<iostream>
using namespace std;

struct Node
{
    int data;
    Node *left;
    Node *right;
    int visit;
};

Node * createNode(int data)
{
    Node * n= new Node();
    n->data=data;
    n->left=NULL;
    n->right=NULL;
    n->visit=0;
    return n;
}

void preorder(Node *root)
{
    if(root==NULL)
        return;
    cout<<root->data<<" ";
    preorder(root->left);
    preorder(root->right);
}


void distantNodes(Node *root,int k)
{
    if(root==NULL || k<0 || root->visit==1)
        return;
    else if(k==0 && root->visit!=1)
    {
        cout<<root->data<<endl;
        root->visit=1;
        return;
    }
    distantNodes(root->left,k-1);
    distantNodes(root->right,k-1);
}


int distantNodesp(Node *root,int data,int k,int *flag)
{
    if(root==NULL || *flag==1)
        return -1;


    if(root->data==data)
    {
        *flag=1;

        distantNodes(root,k);
        root->visit=1;
        return k-1;
    }
    else
    {
        int l=distantNodesp(root->left,data,k,flag);
        if(*flag==1)
        {
            distantNodes(root,l);
            root->visit=1;
            return l-1;
        }

        int r=distantNodesp(root->right,data,k,flag);
        if(*flag==1)
        {
            distantNodes(root,r);
            root->visit=1;
            return r-1;
        }

    }

}

int main()
{
    Node *root=createNode(3);
    root->left=createNode(4);
    root->right=createNode(5);
    root->right->left=createNode(10);
    root->left->left=createNode(6);
    root->left->right=createNode(7);
    root->left->left->left=createNode(8);
    root->left->left->right=createNode(9);
    root->left->right->left=createNode(11);
    root->left->right->right=createNode(12);
    root->left->right->right->left=createNode(15);
    root->left->right->left->left=createNode(13);
    root->left->right->left->right=createNode(14);
    root->left->left->left->left=createNode(16);
    root->left->left->left->right=createNode(17);
    root->left->right->left->right->left=createNode(18);
    root->left->right->left->right->right=createNode(19);
    root->left->right->left->right->left->left=createNode(20);
    root->left->right->left->right->left->right=createNode(21);
    //preorder(root);
    int flag=0;
    distantNodesp(root,11,3,&flag);
    return 0;
}

- bhaskar123 November 27, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
-2
of 4 vote

Correct me if my solution is wrong .

#include<stdio.h>
#include<iostream>
#include<stdlib.h>
using namespace std;
struct node{
    int data;
    struct node *left,*right;
};
struct node* newnode(int data)
{
    struct node* node=(struct node*)malloc(sizeof(struct node));
    node->data=data;
    node->left=node->right=NULL;
}
void printNodes(struct node *root,int level)
{
    if(root==NULL)
        return ;
    if(!level)
        cout<<root->data<<endl;
    printNodes(root->left,level-1);
    printNodes(root->right,level-1);
}
int main()
{
    struct node* root=newnode(10);
    root->left=newnode(20);
    root->right=newnode(30);
    root->left->left=newnode(40);
    root->left->right=newnode(50);
    root->right->left=newnode(100);
    printNodes(root,2);
    return 0;
}

- Chandan Singh October 19, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

ur code not worth reading
no comments
no work
no solve this problem at all

why you use others to read and correct your code and waste time

- lite.on.beta October 20, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

I guess, Chandran is trying to print all nodes at level k from given node.

- Kallu October 20, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

+1, that's a good start.

- S O U N D W A V E October 22, 2013 | Flag


Add a Comment
Name:

Writing Code? Surround your code with {{{ and }}} to preserve whitespace.

Books

is a comprehensive book on getting a job at a top tech company, while focuses on dev interviews and does this for PMs.

Learn More

Videos

CareerCup's interview videos give you a real-life look at technical interviews. In these unscripted videos, watch how other candidates handle tough questions and how the interviewer thinks about their performance.

Learn More

Resume Review

Most engineers make critical mistakes on their resumes -- we can fix your resume with our custom resume review service. And, we use fellow engineers as our resume reviewers, so you can be sure that we "get" what you're saying.

Learn More

Mock Interviews

Our Mock Interviews will be conducted "in character" just like a real interview, and can focus on whatever topics you want. All our interviewers have worked for Microsoft, Google or Amazon, you know you'll get a true-to-life experience.

Learn More