Given the root of a binary search tree, and an integer k, return thekthsmallest value (1-indexed) of all the values of the nodes in the tree.
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
Constraints:
The number of nodes in the tree is n.
1 <= k <= n <= 104
0 <= Node.val <= 104
Follow up: If the BST is modified often (i.e., we can do insert and delete operations) and you need to find the kth smallest frequently, how would you optimize?
Solutions
Solution 1
Thinking
Inorder on a BST is sorted order. We only need the \(k\)-th visited node, not the full list.
An explicit stack walks left, and each pop decrements \(k\); when \(k\) hits \(0\) we have the answer.
1 2 3 4 5 6 7 8 910111213141516171819
# Definition for a binary tree node.# class TreeNode:# def __init__(self, val=0, left=None, right=None):# self.val = val# self.left = left# self.right = rightclassSolution:defkthSmallest(self,root:Optional[TreeNode],k:int)->int:stk=[]whilerootorstk:ifroot:stk.append(root)root=root.leftelse:root=stk.pop()k-=1ifk==0:returnroot.valroot=root.right
/** * Definition for a binary tree node. * type TreeNode struct { * Val int * Left *TreeNode * Right *TreeNode * } */funckthSmallest(root*TreeNode,kint)int{stk:=[]*TreeNode{}forroot!=nil||len(stk)>0{ifroot!=nil{stk=append(stk,root)root=root.Left}else{root=stk[len(stk)-1]stk=stk[:len(stk)-1]k--ifk==0{returnroot.Val}root=root.Right}}return0}
One inorder pass is enough, but repeated queries on a static tree redo the left spine. After storing each subtree size, we compare the left size with \(k\) and walk left or right.
/** * Definition for a binary tree node. * type TreeNode struct { * Val int * Left *TreeNode * Right *TreeNode * } */typeBSTstruct{cntmap[*TreeNode]introot*TreeNode}funcnewBST(root*TreeNode)*BST{varcountfunc(*TreeNode)intcnt:=map[*TreeNode]int{}count=func(root*TreeNode)int{ifroot==nil{return0}n:=1+count(root.Left)+count(root.Right)cnt[root]=nreturnn}count(root)return&BST{cnt,root}}func(bst*BST)kthSmallest(kint)int{node:=bst.rootfornode!=nil{v:=0ifnode.Left!=nil{v=bst.cnt[node.Left]}ifv==k-1{returnnode.Val}ifv<k-1{k-=(v+1)node=node.Right}else{node=node.Left}}return0}funckthSmallest(root*TreeNode,kint)int{bst:=newBST(root)returnbst.kthSmallest(k)}