Open In App

K'th Largest Element in BST when modification to BST is not allowed

Last Updated : 28 Oct, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

Given a Binary Search Tree (BST) and a positive integer k, the task is to find the kth largest element in the Binary Search Tree.

Example: 

Input: k = 3

th-Largest-element-in-BST

Output: 14
Explanation: If we sort the BST in decreasing order, then it will become 22, 20, 14, 12, 10, 8, 4. 14 is the 3rd largest element.

Using Recursion - O(n) Time and O(h) Space

The idea is to traverse the binary search tree in reverse in-order manner. This way we will traverse the elements in decreasing order. Maintain the count of nodes traversed so far. If count becomes equal to k, return the element.

C++
// C++ Program to find kth largest element
#include <bits/stdc++.h>
using namespace std;

class Node {
    public:
        int data;
        Node* left;
        Node* right;
        Node (int x) {
            data = x;
            left = nullptr;
            right = nullptr;
        }
};

// Function which will traverse the BST
// in reverse inorder manner.
int kthLargestRecur(Node* root, int &cnt, int k) {

    // base case
    if (root == nullptr)
        return -1;
        
    int right = kthLargestRecur(root->right, cnt, k);
    
    // if kth largest number is present in
    // right subtree, then return it.
    if (right != -1)
        return right;
    
    // Increment the node count.
    cnt++;
    
    // If root node is the kth largest element,
    // then return it.
    if (cnt == k) 
        return root->data;
        
    int left = kthLargestRecur(root->left, cnt, k);
    
    // else return value provided by
    // left subtree.
    return left;
}

int kthLargest(Node* root, int k) {
    int cnt = 0;
    return kthLargestRecur(root, cnt, k);
}

int main() {
    
    // Create a hard coded tree.
    //         20
    //       /   \
    //      8     22
    //    /  \  
    //   4   12  
    //      /  \
    //     10   14
    Node* root = new Node(20);
    root->left = new Node(8);
    root->right = new Node(22);
    root->left->left = new Node(4);
    root->left->right = new Node(12);
    root->left->right->left = new Node(10);
    root->left->right->right = new Node(14);
    
    int k = 3;
    
    cout << kthLargest(root, k) << endl;
    
    return 0;
}
Java
//Java Program to find kth largest element
import java.util.*;

class Node {
    int data;
    Node left, right;

    Node(int x) {
        data = x;
        left = null;
        right = null;
    }
}

class GfG {
    
    // Function which will traverse the BST in
  	// reverse inorder manner.
    static int kthLargestRecur(Node root, int[] cnt, int k) {
      
        // Base case
        if (root == null)
            return -1;

        // Traverse the right subtree first 
      	// (larger elements)
        int right = kthLargestRecur(root.right, cnt, k);

        // If kth largest number is present in right
      	// subtree, return it.
        if (right != -1)
            return right;

        // Increment the node count.
        cnt[0]++;

        // If root node is the kth largest element,
      	// return it.
        if (cnt[0] == k)
            return root.data;

        // Otherwise, traverse the left subtree.
        return kthLargestRecur(root.left, cnt, k);
    }

    static int kthLargest(Node root, int k) {
        int[] cnt = new int[1];
        return kthLargestRecur(root, cnt, k);
    }

    public static void main(String[] args) {
      
        // Create a hard coded tree.
        //         20
        //       /   \
        //      8     22
        //    /  \  
        //   4   12  
        //      /  \
        //     10   14
        Node root = new Node(20);
        root.left = new Node(8);
        root.right = new Node(22);
        root.left.left = new Node(4);
        root.left.right = new Node(12);
        root.left.right.left = new Node(10);
        root.left.right.right = new Node(14);

        int k = 3;
        System.out.println(kthLargest(root, k));
    }
}
Python
# Python Program to find kth largest element
class Node:
    def __init__(self, x):
        self.data = x
        self.left = None
        self.right = None

def kthLargest(root, k):
  
  	# Use a list to maintain the 
    # count as reference
    count = [0]  
    
    def kthLargestRecur(node):
        if node is None:
            return -1
        
        # Traverse the right subtree
       	# first (larger elements)
        right = kthLargestRecur(node.right)
        if right != -1:
            return right

        # Increment the node count
        count[0] += 1
        if count[0] == k:
            return node.data
        
        # Traverse the left subtree
        return kthLargestRecur(node.left)
    
    return kthLargestRecur(root)

if __name__ == "__main__":
  
    # Create a hard coded tree.
    #         20
    #       /   \
    #      8     22
    #    /  \  
    #   4   12  
    #      /  \
    #     10   14
    root = Node(20)
    root.left = Node(8)
    root.right = Node(22)
    root.left.left = Node(4)
    root.left.right = Node(12)
    root.left.right.left = Node(10)
    root.left.right.right = Node(14)

    k = 3
    print(kthLargest(root, k))
C#
// C# Program to find kth largest element
using System;

class Node {
    public int data;
    public Node left, right;

    public Node(int x) {
        data = x;
        left = right = null;
    }
}

class GfG {
    
    // Function which will traverse the BST
    // in reverse inorder manner.
    static int KthLargestRecur(Node root, 
                               ref int cnt, int k) {

        // base case
        if (root == null)
            return -1;

        int right = KthLargestRecur(root.right, 
                                    ref cnt, k);

        // if kth largest number is present in
        // right subtree, then return it.
        if (right != -1)
            return right;

        // Increment the node count.
        cnt++;

        // If root node is the kth largest element,
        // then return it.
        if (cnt == k)
            return root.data;

        int left = KthLargestRecur(root.left, ref cnt, k);

        // else return value provided by
        // left subtree.
        return left;
    }
    
    static int KthLargest(Node root, int k) {
        int cnt = 0;
        return KthLargestRecur(root, ref cnt, k);
    }
    
    static void Main(string[] args) {

        // Create a hard coded tree.
        //         20
        //       /   \
        //      8     22
        //    /  \  
        //   4   12  
        //      /  \
        //     10   14
        Node root = new Node(20);
        root.left = new Node(8);
        root.right = new Node(22);
        root.left.left = new Node(4);
        root.left.right = new Node(12);
        root.left.right.left = new Node(10);
        root.left.right.right = new Node(14);

        int k = 3;
        Console.WriteLine(KthLargest(root, k));
    }
}
JavaScript
// Javascript Program to find kth largest element
class Node {
    constructor(x) {
        this.data = x;
        this.left = null;
        this.right = null;
    }
}

// Function which will traverse the BST in
// reverse in-order manner
function kthLargestRecur(node, count, k) {

    // Base case
    if (node === null) {
        return -1;
    }

    // Traverse the right subtree first (larger elements)
    let right = kthLargestRecur(node.right, count, k);
    if (right !== -1) {
    
    	// If the k-th largest number
        // is found in the right subtree
        return right; 
    }
    
    count.value++;

    // If root node is the k-th largest
    // element, return it
    if (count.value === k) {
        return node.data;
    }

    // Otherwise, traverse the left subtree
    return kthLargestRecur(node.left, count, k);
}

function kthLargest(root, k) {

	// Use an object to maintain count
    // as reference
    const count = { value: 0 }; 
    return kthLargestRecur(root, count, k);
}

// Create a hard-coded tree.
//         20
//       /   \
//      8     22
//    /  \  
//   4   12  
//      /  \
//     10   14
let root = new Node(20);
root.left = new Node(8);
root.right = new Node(22);
root.left.left = new Node(4);
root.left.right = new Node(12);
root.left.right.left = new Node(10);
root.left.right.right = new Node(14);

let k = 3;
console.log(kthLargest(root, k));

Output
14

Using Stack - O(n) Time and O(h) Space

The idea is to similar to recursion, but in this method, stack will be used to traverse the binary search tree in reverse in-order manner. This way we will traverse the elements in decreasing order. Maintain the count of nodes traversed so far. If count becomes equal to k, return the element.

Below is the implementation of the above approach:

C++
// C++ Program to find kth largest element
// using stack
#include <bits/stdc++.h>
using namespace std;

class Node {
    public:
        int data;
        Node* left;
        Node* right;
        Node (int x) {
            data = x;
            left = nullptr;
            right = nullptr;
        }
};

int kthLargest(Node* root, int k) {
    
    stack<Node*> st;
    Node* curr = root;
    int count = 0;
    
    while (curr != nullptr || !st.empty()) {
        
        // Push the right child child
        // nodes into stack
        while (curr != nullptr) {
            st.push(curr);
            curr = curr->right;
        }
        
        curr = st.top();
        st.pop();
        
        // increment the count
        count++;
        
        // return curr node 
        // if count == k
        if (count == k) {
            return curr->data;
        }
        
        
        curr = curr->left;
    }
    
    return -1;
}


int main() {
    
    // Create a hard coded tree.
    //         20
    //       /   \
    //      8     22
    //    /  \  
    //   4   12  
    //      /  \
    //     10   14
    Node* root = new Node(20);
    root->left = new Node(8);
    root->right = new Node(22);
    root->left->left = new Node(4);
    root->left->right = new Node(12);
    root->left->right->left = new Node(10);
    root->left->right->right = new Node(14);
    
    int k = 3;

    cout << kthLargest(root, k) << endl;
    
    return 0;
}
Java
// Java Program to find kth largest element
// using stack
import java.util.Stack;

class Node {
    int data;
    Node left, right;

    Node(int x) {
        data = x;
        left = right = null;
    }
}

class GfG {

    static int kthLargest(Node root, int k) {
        Stack<Node> st = new Stack<>();
        Node curr = root;
        int count = 0;

        while (curr != null || !st.isEmpty()) {

            // Push the right child nodes 
          	// into stack
            while (curr != null) {
                st.push(curr);
                curr = curr.right;
            }

            curr = st.pop();

            // increment the count
            count++;

            // return curr node if count == k
            if (count == k) {
                return curr.data;
            }

            curr = curr.left;
        }

        return -1;
    }

    public static void main(String[] args) {

        // Create a hard-coded tree:
        //         20
        //       /   \
        //      8     22
        //    /  \
        //   4   12
        //      /  \
        //     10   14
        Node root = new Node(20);
        root.left = new Node(8);
        root.right = new Node(22);
        root.left.left = new Node(4);
        root.left.right = new Node(12);
        root.left.right.left = new Node(10);
        root.left.right.right = new Node(14);

        int k = 3;

        System.out.println(kthLargest(root, k));
    }
}
Python
# Python Program to find kth largest element
# using stack
class Node:
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None

def kth_largest(root, k):
    stack = []
    curr = root
    count = 0

    while curr is not None or stack:

        # Push the right child nodes
        # into stack
        while curr is not None:
            stack.append(curr)
            curr = curr.right

        curr = stack.pop()

        # increment the count
        count += 1

        # return curr node if 
        # count == k
        if count == k:
            return curr.data

        curr = curr.left

    return -1

if __name__ == "__main__":
    
    # Create a hard-coded tree:
    #         20
    #       /   \
    #      8     22
    #    /  \
    #   4   12
    #      /  \
    #     10   14
    root = Node(20)
    root.left = Node(8)
    root.right = Node(22)
    root.left.left = Node(4)
    root.left.right = Node(12)
    root.left.right.left = Node(10)
    root.left.right.right = Node(14)

    k = 3
    print(kth_largest(root, k))
C#
// C# Program to find kth largest element
// using stack
using System;
using System.Collections.Generic;

class Node {
    public int data;
    public Node left, right;

    public Node(int x) {
        data = x;
        left = right = null;
    }
}

class GfG {

    static int KthLargest(Node root, int k) {
        Stack<Node> st = new Stack<Node>();
        Node curr = root;
        int count = 0;

        while (curr != null || st.Count > 0) {

            // Push the right child nodes
          	// into stack
            while (curr != null) {
                st.Push(curr);
                curr = curr.right;
            }

            curr = st.Pop();

            // increment the count
            count++;

            // return curr node if 
          	// count == k
            if (count == k) {
                return curr.data;
            }

            curr = curr.left;
        }

        return -1;
    }

    static void Main(string[] args) {

        // Create a hard-coded tree:
        //         20
        //       /   \
        //      8     22
        //    /  \
        //   4   12
        //      /  \
        //     10   14
        Node root = new Node(20);
        root.left = new Node(8);
        root.right = new Node(22);
        root.left.left = new Node(4);
        root.left.right = new Node(12);
        root.left.right.left = new Node(10);
        root.left.right.right = new Node(14);

        int k = 3;
        Console.WriteLine(KthLargest(root, k));
    }
}
JavaScript
// JavaScript Program to find kth largest element
// using stack
class Node {
    constructor(data) {
        this.data = data;
        this.left = null;
        this.right = null;
    }
}

function kthLargest(root, k) {
    let st = [];
    let curr = root;
    let count = 0;

    while (curr !== null || st.length > 0) {

        // Push the right child nodes
        // into stack
        while (curr !== null) {
            st.push(curr);
            curr = curr.right;
        }

        curr = st.pop();

        // increment the count
        count++;

        // return curr node if
        // count == k
        if (count === k) {
            return curr.data;
        }

        curr = curr.left;
    }

    return -1;
}

// Create a hard-coded tree:
//         20
//       /   \
//      8     22
//    /  \
//   4   12
//      /  \
//     10   14
let root = new Node(20);
root.left = new Node(8);
root.right = new Node(22);
root.left.left = new Node(4);
root.left.right = new Node(12);
root.left.right.left = new Node(10);
root.left.right.right = new Node(14);

let k = 3;
console.log(kthLargest(root, k));

Output
14

Using Morris Traversal Algorithm - O(n) Time and O(1) Space

The idea is to use Reverse Morris Traversal Algorithm to traverse the binary search tree in reverse in-order manner and maintain the count of nodes traversed so far. If number of nodes traversed become equal to k, then return the node. Please refer to K’th Largest element in BST using constant extra space for implementation.


Next Article

Similar Reads