Kth Smallest Element in a BST medium
Problem Statement
Given the root of a binary search tree (BST) and an integer k
, return the kth smallest element in the BST. You can assume k
is always valid, 1 ≤ k
≤ total nodes of the BST.
Example 1:
Input: root = [3,1,4,null,2], k = 1
Output: 1
Example 2:
Input: root = [5,3,6,2,4,null,null,1], k = 3
Output: 3
Steps and Explanation
The key idea is to leverage the properties of a Binary Search Tree (BST). In a BST, an inorder traversal will visit nodes in ascending order. Therefore, we can perform an inorder traversal and keep track of the elements visited. The k-th element encountered during the inorder traversal is the k-th smallest element.
We'll use an iterative approach for inorder traversal to avoid the overhead of recursion. This involves using a stack to keep track of nodes to visit.
- Initialization: Create an empty stack
stack
and initialize a countercount
to 0. - Iteration: While the stack is not empty or the current node is not
None
:- If the current node is not
None
: push the node onto the stack and move to its left child (current = current.left
). This ensures we process the left subtree first. - Otherwise (if the current node is
None
): pop a node from the stack. This node is the next smallest node in the inorder traversal. Increment thecount
. Ifcount
equalsk
, this popped node's value is the k-th smallest element, so return its value. Then, move to the right child of the popped node (current = current.right
).
- If the current node is not
Code
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def kthSmallest(root, k):
stack = []
count = 0
current = root
while stack or current:
while current:
stack.append(current)
current = current.left
current = stack.pop()
count += 1
if count == k:
return current.val
current = current.right
return -1 # Should not reach here if k is valid
# Example usage
root1 = TreeNode(3)
root1.left = TreeNode(1)
root1.right = TreeNode(4)
root1.left.right = TreeNode(2)
root2 = TreeNode(5)
root2.left = TreeNode(3)
root2.right = TreeNode(6)
root2.left.left = TreeNode(2)
root2.left.right = TreeNode(4)
root2.left.left.left = TreeNode(1)
print(kthSmallest(root1, 1)) # Output: 1
print(kthSmallest(root2, 3)) # Output: 3
Complexity Analysis
- Time Complexity: O(H + k), where H is the height of the BST. In the worst case (a skewed BST), H can be O(N), where N is the number of nodes. However, for a balanced BST, H is O(log N). The inorder traversal visits at most k nodes.
- Space Complexity: O(H) in the worst case due to the stack used for the iterative inorder traversal. For a balanced BST, this becomes O(log N), and for a skewed BST, it's O(N).