Facebook Interview Question for Software Engineer / Developers


Country: United States




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

Traverse in reverse in-order (i.e. descending order).


Something like this (quick code without thinking, so bugs will be there).

Tree * Largest(Tree *root, const int k) {
    int count = 0;
    return LargestHelper(root, k, count);
}
// Return either NULL (not found), or returns the node.
Tree *LargestHelper(Tree *root, const int k, int &count) {
    if (root == NULL) {
        return NULL;
    }
    
    Tree *right = LargestHelper(root->right, k, count);
  
    if (right != NULL) return right;
   
    count++;
    if (count == k) {
        return root;
    }
       
    return LargestHelper(root->left, k, count);
}

- Loler March 03, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Perfect! :) Except for small syntax error, this code is logically correct! :)

- jtr.hkcr March 03, 2013 | Flag
Comment hidden because of low score. Click to expand.
1
of 1 vote

@jtr. Thanks! I looked but could not find the syntax error. Can you please tell me?

Note: I had edited it once, but that seemed to be before you commented.

- Loler March 03, 2013 | Flag
Comment hidden because of low score. Click to expand.
1
of 1 vote

@Loler, you edited that error out. You had "right = NULL" or something before declaring "Tree *right".

This is the short and sweet answer at the moment! :)

- jtr.hkcr March 03, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

@jtr: Ah, I did have it at one point. Thanks!

- Loler March 03, 2013 | Flag
Comment hidden because of low score. Click to expand.
1
of 1 vote

The key insight here is that you need a helper function to manage the rank. Here's my take on it, with tests:

#include <stdlib.h>
#include <stdio.h>
#include <assert.h>

struct Node {
    int val;
    struct Node *left;
    struct Node *right;
};
typedef struct Node Node;

struct search_result {
    int need;
    struct Node *node;
};

struct search_result kth_biggest_result(Node *root, int k) {
    struct search_result sr;
    sr.need = k;
    sr.node = NULL;
    if (!root) {
        return sr;
    }
    if (root->right) {
        sr = kth_biggest_result(root->right, k);
        if (sr.need == 0) return sr;
    }
    sr.need -= 1; // root
    if (sr.need == 0) {
        sr.node = root;
        return sr;
    }
    return kth_biggest_result(root->left, sr.need);
}

Node *kth_biggest(Node *root, int k) {
    struct search_result sr;
    sr = kth_biggest_result(root, k);
    return sr.node;
}

Node *make_node(int n) {
    Node *Node = malloc(sizeof(struct Node));
    Node->left = NULL;
    Node->right = NULL;
    Node->val = n;
    return Node;
}

int main(int argc, char **argv) {
    Node *node;
    Node *t1 = make_node(1);
    Node *t2 = make_node(2);
    Node *t3 = make_node(3);
    Node *t4 = make_node(4);
    Node *t5 = make_node(5);
    Node *t6 = make_node(6);
    t2->left = t1;
    t2->right = t3;
    t4->left = t2;
    t4->right = t5;
    t5->right = t6;
    node = kth_biggest(t4, 1);
    assert(node->val == 6);
    node = kth_biggest(t4, 2);
    assert(node->val == 5);
    node = kth_biggest(t4, 3);
    assert(node->val == 4);
    node = kth_biggest(t4, 4);
    assert(node->val == 3);
    node = kth_biggest(t4, 5);
    assert(node->val == 2);
    node = kth_biggest(t4, 6);
    assert(node->val == 1);
    node = kth_biggest(t4, 7);
    assert(!node);
    node = kth_biggest(t4, 8);
    assert(!node);

    return 0;
}

- showell30@yahoo.com March 04, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

nice trick ,this is better than my solution

- duckling March 04, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Very nice. though assuming only that k is small is not enough ( or the wrong assumption) instead you have to assume the k largest is on the right side of the root.
e.g: insert 2,3,1 or 4,2,3 in the bst. find 3rd largest returns wrong node (null).

- kz March 04, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Loler, I'm confused why you're returning the right child if root.right isn't null.

- Frank March 04, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes
Here's my java implementation. {{{{ TreeNode kthLargest(TreeNode t, int k){ if(t == null){ return null; } kthLargest(t.right, k); k--; if(k <= 0){ return t; } else { return kthLargest(t.left, k); } - Frank March 04, 2013 | Flag
Comment hidden because of low score. Click to expand.
1
of 1 vote

ooops sorry about formatting.

TreeNode kthLargest(TreeNode t, int k){ 
    if(t == null){ 
        return null; 
    } 
    kthLargest(t.right, k); 
    k--; 
    if(k <= 0){ 
        return t; 
    } else { 
        return kthLargest(t.left, k); 
    }
}

- Frank March 04, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

@kz: We cannot dispute assumptions like that :-) They will be dictated by the needs of the requirements (or the interviewer in this case), which we don't have access to.

I just stated that to prefer reverse inorder over inorder. That is all.

In any case, if we don't know the total number of nodes in the tree, doing a reverse inorder will be more efficient than counting the nodes and then doing an inorder traversal to find the (n-k)^th smallest.

I have updated the original post to not talk of any assumptions at all.

- Loler March 04, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

@Frank: I am not returning root.right.

I am returning the element found in the right subtree. (perhaps the variable name is misleading...)

- Loler March 04, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

@Frank is your code in Java? I don't think it will work because after traversing the right subtree k will still be equal to the value before the traversal since decrementing k in the recursion doesn't affect the caller's k. The C code equivalent works because you can pass a pointer to an int, but not in Java.

There are two ways around this in Java:
1. Make k a member of the class instead of a parameter. (worse)
2. Create a new inner class K { int k; } and pass that instead. (better)

Check out my code. It is similar to yours but uses the K structure.

- Barry Fruitman March 15, 2013 | Flag
Comment hidden because of low score. Click to expand.
2
of 2 vote

struct Node {
    int val;
    struct Node *left;
    struct Node *right;
} Node;

struct Node * kth_largest(struct Node *root, unsigned int k);
{
	if( ! root )
		return NULL;
	int pos = 0;
	return kth_largest_helper(root, k, &pos);
}

/* 
   Help find the kth_largest by comparing the rank of root from 
   the largest/rightmost node in the BST.
*/
struct Node *kth_largest_helper(struct Node *root, unsigned int k , int *rank)
{
	if( ! root )
		return root;

	struct Node *temp = NULL ;
	if( root-> right )
	{
		/* we have not seen the rightmost node yet => rank ordering has not started */
		temp = kth_largest_helper(root->right, k, rank);
	
		if ( temp )
			return temp;
	}
	(*rank)++; // increment position rank
	
	if( *rank == k )
		return root; // kth element

	return root->left ? kth_largest_helper(root->left, k, rank) : temp;
}

- jean March 03, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Except for some code cleanup this is perfect! :)

- jtr.hkcr March 03, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Wouldn't this return (n-k)the largest element?
If you want to to find Kth largest shouldn't you find rank with respect to leftmost node?

- AlertCoder March 03, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Ignore my comment

- AlertCoder March 03, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

nice logic :@jean

- ajit March 10, 2013 | Flag
Comment hidden because of low score. Click to expand.
1
of 3 vote

void kthlargest(struct Node *node,int k,int &index,int &res)
{
if(!node || index>k)
return;
kthlargest(node->right,k,index,res);
index++;
if(k==index)
{
res=node->data;
}
kthlargest(node->left,k,index,res);
}

- Anonymous March 03, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Didn;t notice that prototype is given.. so the code according to prototype is given in this answer.

struct Node *Largest(struct Node *node, int k, int &index) {
if (node == NULL) {
return NULL;
}
struct Node *right = Largest(node->right, k, index);
if (right != NULL) return right;
if (index == k-1) {
return node;
}
index++;
return Largest(node->left, k,index);
}

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

This is quite inefficient (original post). You will traverse the whole tree, won't you?

- Loler March 04, 2013 | Flag
Comment hidden because of low score. Click to expand.
1
of 1 vote

My solution in Java. I created a class K to hold k since an int will not work with recursion.

Like the solutions above, it performs a reverse in-order traversal.

public class FindKthLargest {

	Node kthLargest(Node root, int ik) {
		// Create a new "K"
		K k = new K(ik);

		// Traverse the tree from largest to smallest
		return reverseIOT(root, k);
	}

	
	/**
	 * Traverse a subtree in reverse in-order (right,node,left)
	 * @param node	The subtree to traverse
	 * @param k		Exit with k.k == 0
	 * @return		The kth largest node
	 */
	private Node reverseIOT(Node node, K k) {
		if(node == null)
			return null;
	
		Node n = reverseIOT(node.right, k);
		if(n != null)
			return n;

		if(--k.k == 0)
			return node;
			
		return reverseIOT(node.left, k);
	}


	/**
	 * Node class as defined by problem
	 */
	private static class Node {
		private Node(int value) {
			this.value = value;
		}
		private final int value;
		private Node left;
		private Node right;
		
		public String toString() {
			return String.valueOf(value);
		}
	}


	/**
	 * This class holds a mutable integer
	 */
	private class K {
		private int k;
		
		private K(int k) {
			this.k = k;
		}
	}
	
	
	
	/**
	 * Test harness
	 * @param args	Ignored
	 */
	public static void main(String args[]) {
		Node node1 = new Node(1);
		Node node2 = new Node(2);
		Node node3 = new Node(3);
		Node node4 = new Node(4);
		Node node5 = new Node(5);
		Node node6 = new Node(6);
		Node node7 = new Node(7);
		
		node4.left  = node2;
		node4.right = node6;
		node2.left  = node1;
		node2.right = node3;
		node6.left  = node5;
		node6.right = node7;
	
		FindKthLargest app = new FindKthLargest();

		System.out.println(app.kthLargest(node4, 5));
	}

}

- Barry Fruitman March 15, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

Whenever you recurse on reverseIOT, you are essentially returning/mutating two values: the node and a new k. The node goes from NULL to an actual node (if found), or remains the same. The number k goes from its original value to a lesser value (if the right tree has nodes), or remains the same. So, in some sense k and node really are similarly mutable. When you call a function that mutates two values, you can tackle it three ways:

1) Have the function mutate both values.
2) Have the function mutate one value and return the other.
3) Have the function return new copies of both values.

You chose solution #2, and I have no problem with that decision, but I'm curious at how you arrived at it.

In my implementation I chose strategy #3. I don't believe I've seen anyone choose strategy #1, but it would be conceptually easy as well. You call a function that sets the node if it's found; otherwise; it decrements k as needed.

You're not the only person that chose #2, but it seems asymmetrical to me. The other thing that seems strange to me is that you have a class that does nothing but wrap an integer to mutate it.

I like the clear code and tests, so I am upvoting this, by the way.

- showell30@yahoo.com March 15, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Thanks for the upvote.

Since all three solutions are semantically equivalent, as you pointed out, I chose #2 because a node is the ultimate return value so it made sense to implement it as such. As well, in my view k is a parameter so I made it one. I guess my solution is asymmetric because the two pertinent values are asymmetric.

I originally implemented solution #1 (but didn't post it) and viewed it as more-or-less equivalent to #3, the only difference being how the two values are returned to the caller (mutation vs. return value). I also defined a class similar to your search_result but changed it because I saw no need to combine the two values in one data structure. I believe the difference between our approaches is a matter of preference, not correctness.

I agree my K class is a little strange but I really liked the C solutions that passed a pointer to k and wanted my solution to work the same way.

- Barry Fruitman March 15, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

traverse inorder, return the kth node traversed

- Anonymous March 03, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

code please....

Test case: If the elements were 1, 4, 6, 7, 11, 23, 99 and 100; 2nd largest (k=2) will be 99.

- jtr.hkcr March 03, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

#include <stdio.h>
struct Node {
        int val;
        struct Node *left;
        struct Node *right;
};
typedef struct Node node;

int in_sort[100];
int index=0;

node *c_node(int val)
{
        node *temp = malloc(sizeof(node *));
        temp->val = val;
        temp->left = NULL;
        temp->right = NULL;
        return temp;
}

node * kth_largest(node *root, unsigned int k)
{
        if(k == 0) {
                printf("what are you looking for?I will killl you");
                return NULL;
        }
        return c_node(in_sort[k-1]);
}

void in_node(int val, node **arg)
{
        if(*arg == NULL) { /* empty case */
                *arg = c_node(val);
        } else {
                if(val <= (*arg)->val) {
                        in_node(val, &((*arg)->left));
                } else {
                        in_node(val, &((*arg)->right));

}
}
}

void print(node *head)
{
if(head == NULL)
return;
print(head->left);
in_sort[index++] = head->val;
print(head->right);
}

int main()
{
node *head = NULL;
int k;

/* hardcoded elements to be added */
in_node(10, &head);
in_node(20, &head);
in_node(30, &head);
in_node(0, &head);
in_node(5, &head);

printf("which largest you want to find?\n");
scanf("%d", &k);

print(head);
printf("%d largest is %d\n", k, kth_largest(head, k)->val);
return 0;
}

- try March 03, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>

typedef struct tree
{
int data;
struct tree* left;
struct tree* right;
}TREE;


TREE* createNode(int x)
{
TREE *ptr;
ptr=(TREE*)malloc(sizeof(TREE));
ptr->data=x;
ptr->left=NULL;
ptr->right=NULL;
return ptr;
}






void kthLargest(TREE *root,int *kth,int k)
{
static int counter=0;
if(root==NULL)
return;
else
{



kthLargest(root->left,kth,k);
counter=counter+1;
if(k==counter)
{
*kth=root->data;
return;

}

printf("%d",counter);
kthLargest(root->right,kth,k);


}


}
int getCount(TREE *ptr)
{
if(ptr==NULL)
return 0;
else
return 1+getCount(ptr->left)+getCount(ptr->right);

}

TREE *root;
void initialize()
{
root=NULL;
}

int main()
{

initialize();
root=createNode(8);
root->left=createNode(6);
root->right=createNode(11);
root->left->left=createNode(5);
root->left->right=createNode(7);
root->left->left->left=createNode(4);
root->right->left=createNode(10);
root->right->right=createNode(13);
int kth,k;
k=5;
kth=0;
kthLargest(root,&kth,getCount(root)-k+1);
printf("\n the kth largest number =%d",kth);
return 0;

}

- jkl March 03, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

traverse the tree in inorder try to find kth_temp element which is equal to kth_temp=number of nodes - (k-1).
Suppose taking above comment example kth_temp = 8(num of nodes)-(2(k)-1)=7th.
and 7th element is 99 that is the answer.

- nishant March 03, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

1) count the total number of nodes in the BST,one pass traversal,time cost:O(n)
2) traverse inorder, the (n-k+1)-th smallest node is the answer,time cost:O(n)
below are the C++ code

int CountNode(Node* root)
{
	if(root==NULL)return 0;
	return 1+ CountNode(root->left) + CountNode(root->right);
}
Node * kth_smallest(Node *root, unsigned int k)
{
	if(root == NULL)return NULL;
	Node* ans = kth_smallest(root->left,k);
	if(ans != NULL)return ans;
	if(k==1)return root;
	k--;
	return kth_smallest(root->right,k):
}
Node * kth_largest(Node *root, unsigned int k)
{
	int n = CountNode(root);
	return kth_smallest(root,n-k+1);
}

- duckling March 03, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

What is the logic of kth_smallest()? Seems that function is wrong. Please test.

- jtr.hkcr March 03, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

@jtr.hkcr ,sorry,i typed it in a hurry,corrected.
the basic idea is inorder traverse the BST, so the nodes are traversed in their sorted order,then the k-th node we traverse is the k-th smallest node

- duckling March 03, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Node iterativeInorderForKthLargest(Node root, int k) {
	Stack s = new Stack();
	s.push(new NodeWatchedCount(root, 1));
	int currentLargest = 0;
	while(!s.isEmpty()) {
		NodeWatchedCount n = s.pop();
		if(n.count == 2) {
			currentLargest++;
			if(currentLargest == k) {
				return n.node;
			}
			s.push(new NodeWatchedCount(n.node.right, 1));
		} else {
			n.count = 2;
			s.push(n);
			s.push(n.left);
		}
	}
}

NodeWatchedCount {
	int count;
	Node node;
}

- Anonymous March 03, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

correction:

else {
	n.count = 2;
	s.push(n);
	s.push(new NodeWatchedCount(n.left, 1));
}

- Anonymous March 03, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

if k < n/2 then it will be in right subtree
else it'll be in right subtree
halve the limit and repeat until there is only 1 element between previous iteration and current iteration which will be the kth largest number

O(log(n))

- Anonymous March 03, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

k < n/2 does not mean it will be in the right subtree. You are making an assumption which isn't even true for balanced trees.

But yes, in case we have the counts, something like this is the way to go. You compare the counts and can decide which branch to take.

- Loler March 04, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

right, root, left traversal

- zhou0620 March 03, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Hello,
I have a inorder method to solve this problem.
I used showell30@yahoo.com's code to create the BST, thanks.

#include <stdlib.h>
#include <stdio.h>
#include <assert.h>

struct Node {
    int val;
    struct Node *left;
    struct Node *right;
};
typedef struct Node node_t;

void find_by_inorder(node_t *root, int *count, node_t **result, int k)
{
    if (root != NULL) {
        find_by_inorder(root->right, count, result, k);
        (*count)++;
        if (*count == k) {
            *result = root;
            return;
        }
        find_by_inorder(root->left, count, result, k);
    }
}

node_t *make_node(int n) {
    node_t *node = malloc(sizeof(node_t));
    node->left = NULL;
    node->right = NULL;
    node->val = n;
    return node;
}

int main(int argc, char **argv) {
    node_t *node;
    node_t *t1 = make_node(1);
    node_t *t2 = make_node(2);
    node_t *t3 = make_node(3);
    node_t *t4 = make_node(4);
    node_t *t5 = make_node(5);
    node_t *t6 = make_node(6);
    t2->left = t1;
    t2->right = t3;
    t4->left = t2;
    t4->right = t5;
    t5->right = t6;
    node_t *result = NULL;
    int count = 0;
    int i;
    for (i = 0; i < 10; i++) {
        find_by_inorder(t4, &count, &result, i);
        if (result != NULL)
            printf("%dth: %d\n", i, result->val);
        result = NULL;
        count = 0;
    }
    return 0;
}

- shuaiwhu March 04, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

As everybody has figured out we can solve it in O(n) using inorder:

node *kthLargest(node *root, int &k){
    if(root == NULL)
        return NULL;
        
    node *n = kthLargest(root->left, k);
    if(n != NULL) return n;
    k -=1;
    if(k == 0) return root;
    
    n = kthLargest(root->right, k);
    return n;
}

But, if we are allowed to modify the tree node, we can add "size" integer member in it and then sizeify the tree. root->size = size of the subtree rooted at root.
Here is a code snippet to calculate the size of all the possible subtrees:

int sizeifyBST(node *&root){
    if(root == NULL){
        return 0;
    }
    
    int leftsize = sizeifyBST(root->left);
    int rightsize = sizeifyBST(root->right);
    return root->size = leftsize + rightsize + 1;
}

Now, we can easily find kth largest in O(logn):
suppose we are at node T:
1. k == size of the left subtree + 1, then return T
2. if k > size of the left subtree + 1, then recursively call the same method with k = k - size of the left subtree
3. if k < size of the left subtree, then go left with same k

node *findKthLargestFaster(node *root, int k){
    if(root == NULL) return NULL;
    
    int leftsubtreesize = root->size
                            - (root->right?root->right->size:0)
                            - 1;
    
    if(k == leftsubtreesize + 1)
        return root;
    else if(k < leftsubtreesize + 1)
        return findKthLargestFaster(root->left, k);
    else
        return findKthLargestFaster(root->right, k - leftsubtreesize-1);
}

Here is the link to the working code, if you guys are interested:
ideone.com/Qkkkl6

- HauntedGhost March 04, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 votes

@Kevindra, the inorder method you posted should go to the right subtree first and then the left subtree to find the kWh largest.

Nice logic to convert to O(logn) complexity, given the tree is balanced.

- jtr.hkcr March 04, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 votes

Thanks! Yeah i mistakenly put left call first. the method i actually wrote is for finding k-smallest number. :)

- HauntedGhost March 04, 2013 | Flag
Comment hidden because of low score. Click to expand.
0
of 0 vote

Solution in C:

#include <stdio.h>
#include <stdlib.h>

typedef struct Node {
  int val;
  struct Node *left;
  struct Node *right;
} Node;

static Node* dokth_largest(Node* n, unsigned int* k)
{
  if ( ! k )
    return NULL;
  Node* tmp = NULL;
  if ( n->left )
    tmp = dokth_largest(n->left, k);
  if ( tmp )
    return tmp;
  if ( *k == 0 )
    return n;
  --(*k);
  if ( n->right )
    tmp = dokth_largest(n->right, k);
  return tmp;
}

Node* kth_largest(Node *root, unsigned int k)
{
  return dokth_largest(root, &k);
}

int main()
{
  Node n1 = { 1, NULL, NULL };
  Node n3 = { 3, NULL, NULL };
  Node n2 = { 2, &n1, &n3 };
  Node n5 = { 5, NULL, NULL };
  Node n6 = { 6, &n5, NULL };
  Node n4 = { 4, &n2, &n6 };
  Node* n = kth_largest(&n4, 4);
  if ( n )
    printf("%d\n", n->val);
  else
    printf("not found\n");
}

- cosmin March 18, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Java version:

static class Node {
		int val;
		Node right = null;
		Node left = null;
	}

	static int countNodes(Node root) {
		if (root == null)
			return 0;
		else
			return countNodes(root.left) + 1 + countNodes(root.right);
	}

	private static Node kthLargest(Node root, int k) {
		if (k == 0 || root == null)
			return null;
		int r = countNodes(root.right);
		if (r == k-1) return root;
		else if (r>=k) return kthLargest(root.right, k);
		else return kthLargest(root.left, k-r-1);
	}

- cengin May 17, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

/// Using Some Method Like mid-order Trans

TNode * kth_largest(TNode * root, int k, int & count)
{
    if(NULL == root) return NULL;
    TNode * r1 = kth_largest(root->right, k, count);
    if(NULL != r1) return r1; 
    count ++; 
    if(k == count) return root;
    TNode * r2 = kth_largest(root->left, k, count);
    if(NULL != r2) return r2; 
    return NULL;
}

- zombie July 17, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

A solution using Inorder iterator, and call Next() k times.

class InOrderIterator
{
public:
    InOrderIterator(const Node* const root)
    {
        TraverseLeftMostPath(root);       
    }

    const Node* Next()
    {
        if (m_stack.size() == 0) return NULL;

        const Node* curNode = m_stack.Pop();
        if (curNode->Right)
        {
            TraverseLeftMostPath(curNode->Right);
        }
        return curNode;
    }
private:
    void TraverseLeftMostPath(const Node* const node)
    {
        while (node && node->Left)
        {
            m_stack.Push(node);
            node = node->Left;
        }
    }
    Stack<shared_ptr<Node>> m_stack;
}

const Node* root = CreateTree(1000);
InOrderInterator iterator(root);
for (size_t i = 0; i < k; ++i)
{
    printf_s("%s\n", iterator.Next()->ToString());
}

- Mamamia August 02, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

The famous algorithms book -- "Introduction to Algorithms" actually contains a solution
to the problem. It's idea is to first find the minimum node of the tree, and then traverse from it and find its kth SUCCESSOR.

Please check out the detials from 12.2-7, Chapter 12 of CLRS, Second edition.

FIND-KTH-LARGEST(x, k)
    x = TREE-MINIMUN(x)
    while k > 0
        x = TREE-SUCCESSOR(x)
        k = k - 1
    return x

where procedures TREE-MINIMUN and TREE-SUCCESSOR have been given in previous pages.

- A solution drawn from CLRS October 06, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

Node *find_k_largest_node(Node *n, int k) {
stack<Node*> s;
bool done = false;

while (!done) {
if (n) {
s.push(n);
n = n->left;
}
else {
if (s.empty()) {
done = true;
}
else {
n = s.top();
s.pop();

k--;

if (k == 0) {
return n;
}

n = n->right;
}
}
}

return NULL;
}

- Gerald November 17, 2013 | Flag Reply
Comment hidden because of low score. Click to expand.
0
of 0 vote

public class SelectionOnBST {
	
	class Node {
		int v;
		Node left, right;
		
		public Node(int v){
			this.v = v;
			left = right = null;
		}
	}
	
	static class Pair {
		Node n;
		int x;
		
		public Pair(Node n, int x){
			this.n = n;
			this.x = x;
		}
	}
	
	public SelectionOnBST() {
	}

	/**
	 * Assume read only nodes, cannot store heights
	 */
	static Node findKthLargestElement(Node root, int k){
		Pair p = helper(root, k);
		if( p == null){
			return null;
		} else {
			return p.n;
		}
	}
	
	static Pair helper(Node root, int k){
		int numExamined = 0;
		if(root == null || k <=0){
			return new Pair(null,0);
		} else if(root.right == null && root.left == null){
			numExamined = 1;
			if(k == 1){
				// found
				return new Pair(root, k);
			} else {
				return new Pair(null, 1);
			}
		} else if(root.right != null){
			Pair p = helper(root.right,k);
			numExamined = p.x;
			if(numExamined == k){
				// found
				return p;
			}
		}
		
		if(numExamined == (k-1)){
			// found
			return new Pair(root,k);
		} else {
			numExamined++;
		}
		
		if(root.left != null){
			Pair p = helper(root.left, k-numExamined);
			// found
			if(p.n != null){
				p.x = k;
				return p;
			} else {
				numExamined += p.x; 
			}
		}
		
		return new Pair(null,numExamined);
	}
}

- just_do_it March 06, 2015 | Flag Reply


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