Amazon Interview Question
SDE1sCountry: India
Nice approach..but you code may not run :) Modified code is..
void kthlargest(Node *root,int k)
{
static int count;
if(root){
kthlargest(root->right,k);
count++;
if(k==count){
printf("%d",root->data);
}
kthlargest(root->left,k);
}
}
@Sandeep: Please check..this is reverse of inorder traversal..it means..it will print data in decreasing(eg..5,4,3,2,1) order. Now to find 2nd largest element..it will print 4.
You have not initialized count. Even if you initialize it to 0, it will give you the wrong rank!
Yes, this is wrong. You never return the actual value in most cases. Though it is close to an answer which might work. But since you have no explanation whatsoever, I chose to downvote this. On the basis of the code alone(it is incorrect and you use static), this is enough to get a bad score on an interview.
The same question was asked a few days back, under Facebook.
Perform reverse in-order traversal of the given BST and return when the k-th element is found.
int count = 0;
Stack S;
while n != null) {
S.push(n);
n = n.right;
}
while (S.size() > 0) {
n = s.pop();
count++;
if (count == k) {
return n.value;
}
if n.left != null) {
n = n.left;
while (n!= null) {
s.push(n);
n = n.left;
}
}
}
System.out.println("ERROR : k > numver of nodes in the tree");
1. Traverse BST in in-order and push elements in stack
2. Pop the elements from stack. At Kth pop, we will get Kth largest element
Hey Kalyan ... once you have inorder traversal you can find the kth largest element in O(1) as the elements will be in increasing order. So i think without stack jus writing elements into an array while traversing and then w.r.t index required we will know the kth max element in O(1).
traversing BST and then putting element in stack leads to memory complicity to O(2n). It can be done in single go:
void kthlargest(Node *root,int k)
{
static int count;
if(root){
kthlargest(root->right,k);
count++;
if(k==count){
printf("%d",root->data);
}
kthlargest(root->left,k);
}
}
void getKthLargestElement(Node *root, int k){
int num = 0;
count(root, &num);
getKthSmallestElement(root,num-k+1,num);
}
//To find kth smallest element in in BST
void getKthSmallestElement(Node *root, int k, int num){
static int count, found;
if(root && !found ){
getKthSmallestElement(root->left, k, num);
count++;
if(count == k){
printf("%d",root->data); found =1; return;
}
else if(count == num && !found){
printf("\nData not found"); return;
}
getKthSmallestElement(root->right, k, num);
}
}
void count(Node *root, int *p){
if(root){
count(root->left, &(*p));
(*p)++;
count(root->right, &(*p));
}
}
No recursion, beat that.
And traverses as minimum nodes as required.
private static int getKthLargest(TreeNode root , int k) {
int fixedIndex=0;
List<TreeNode> list = new ArrayList<TreeNode>();
fillRightSideNodes(list,root,fixedIndex);
while(fixedIndex<=list.size()){
if ( fixedIndex>=list.size()){return -1;}
if ( fixedIndex==k-1){return list.get(fixedIndex).getValue();}
fillRightSideNodes(list,list.get(fixedIndex).getLeftSubTree(), fixedIndex+1);
fixedIndex++;
}
return -1;
}
private static void fillRightSideNodes(List<TreeNode> list, TreeNode root,
int index) {
while ( root != null ){
list.add(index,root);
root=root.getRightSubTree();
}
}
You seem to be attempting to simulate an iterative in-order (in reverse) traversal using a list...
I guess one can beat that, by actually using a stack instead, where you get to pop off/reuse the stack data, thereby restricting the space usage to O(h) (height of tree), while your space usage is potentially Omega(n) (number of nodes in tree) (you only append to your 'stack').
Also, inspite of it being pseudo code, it looks quite ugly. So writing cleaner code which is easier to understand will better that, I suppose. (Perhaps not me, as I find most of my code ugly too)
Your comment needs correction in each line :
1. Its not even a complete traversal of the tree. As I've already written,
I traverse only as few nodes as needed. ( Only the right most ones )
2. I'm using the list as a stack itself. ( The words pop/ push need not always be there to tell you that its a stack )
3. The maximum size the list will grow is not equal to number of nodes in the tree, if you got #1.
4. Its not pseudo code. Its a complete running java code. The Node structure is not pasted as they are too trivial.
public static void findKthElement(Tree node , int k)
{
if(node == null)
{
System.out.println("TREE NULL");
return;
}
Stack<Tree> stack = new Stack<>();
int n =0 ;
while(true)
{
while(node != null)
{
stack.add(node);
node = node.right;
}
if(stack.isEmpty())
{
System.out.println("ELEMENT COUNT OUT OF RANGE");
return;
}
node = stack.pop();
n++;
if(n == k)
{
System.out.println("THE KTh ELEMENT: "+ node.getValue());
return;
}
node = node.left;
}
}
TreeNode kthLargest(TreeNode t, int k) {
if (t == null){
return null;
}
return kthLargest(t.right, k);
k--;
if (k == 0){
retrun t;
}
return kthLargest(t.left, k);
}
struct Node {
int value;
Node *left;
Node *right;
};
//return: true find, false not find
//param:
// count: the number of nodes in the subtree
// ans: the kth largest number
bool find_kth_large(Node *root, int k, int &count, int &ans)
{
if (NULL == root) {
count = 0;
return false;
}
int right_count = 0;
if (find_kth_large(root->right, k, right_count, ans)) {
return true;
}
if (right_count + 1 == k) {
ans = root->value;
return true;
}
int left_count = 0;
if (find_kth_large(root->left, k - 1 - right_count, left_count, ans)) {
return true;
}
count = left_count + right_count + 1;
return false;
}
augmenting the bst can also work. The bst should be augmented with the total no of children in its tree
class KthLargestBST{
protected static int findKthLargest(BSTNode root,int k){
int [] result=findKthLargest(root,k,0);
return result[1];//the element we are looking for.
}
private static int[] findKthLargest(BSTNode root,int k,int count){//returns an array containing 2 ints..one for counts and the other for result.
if(root==null){
int[] i=new int[2];
i[0]=-1;
i[1]=-1;
return i;
}else{
int rval[]=new int[2];
int temp[]=new int[2];
rval=findKthLargest(root.rightChild,k,count);
if(rval[0]!=-1){
count=rval[0];
}
count++;
if(count==k){
rval[1]=root.data;
}
temp=findKthLargest(root.leftChild,k,(count));
if(temp[0]!=-1){
count=temp[0];
}
if(temp[1]!=-1){
rval[1]=temp[1];
}
rval[0]=count;
return rval;
}
}
public static void main(String args[]){
BinarySearchTree bst=new BinarySearchTree();
bst.insert(6);
bst.insert(8);
bst.insert(7);
bst.insert(4);
bst.insert(3);
bst.insert(4);
bst.insert(1);
bst.insert(12);
bst.insert(18);
bst.insert(15);
bst.insert(16);
bst.inOrderTraversal();
System.out.println();
System.out.println(findKthLargest(bst.root,7));
}
}
Some people already did this using C and a static counter. This is using Java and no counter.
This is just a right leaning in-order traversal.
When the counter becomes zero we are done.
void printKthLargest(Node n, int k) {
if( n==null)
return ;//reached root's parent
printKthLargest(n.right, k);
if( k == 0) {
System.out.println(k);
return;
}
k--;
printKthLargest(n.left, k);
}
- swati March 06, 2013