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?
Solution 1: (Standard inorder traverse)
一个直接的思路就是升序排序,然后找第 k 个元素呗。BST 的中序遍历其实就是升序排序的结果,找第 k 个元素肯定不是什么难事。
/**
* Definition of TreeNode:
* public class TreeNode {
* public int val;
* public TreeNode left, right;
* public TreeNode(int val) {
* this.val = val;
* this.left = this.right = null;
* }
* }
*/
public class Solution {
/**
* @param root: the given BST
* @param k: the given k
* @return: the kth smallest element in BST
*/
public int kthSmallest(TreeNode root, int k) {
Map<TreeNode, Integer> numOfChildren = new HashMap<>();
countNodes(root, numOfChildren);
return quickSelectOnTree(root, k, numOfChildren);
}
private int countNodes(TreeNode root, Map<TreeNode, Integer> numOfChildren) {
if (root == null) {
return 0;
}
int left = countNodes(root.left, numOfChildren);
int right = countNodes(root.right, numOfChildren);
numOfChildren.put(root, left + right + 1);
return left + right + 1;
}
private int quickSelectOnTree(TreeNode root, int k, Map<TreeNode, Integer> numOfChildren) {
if (root == null) {
return -1;
}
int left = root.left == null ? 0 : numOfChildren.get(root.left);
if (left >= k) {
return quickSelectOnTree(root.left, k, numOfChildren);
}
if (left + 1 == k) {
return root.val;
}
return quickSelectOnTree(root.right, k - left - 1, numOfChildren);
}
}
Submitted from LeetCode:
class Solution {
Map<TreeNode, Integer> map = new HashMap<TreeNode, Integer>();
int result = 0;
public int kthSmallest(TreeNode root, int k)
{
//maintain a mapping have every node location info
countChildNode(root);
helper(root, k);
return result;
}
public int countChildNode(TreeNode root)
{
if(root == null)
{
return 0;
}
int left = countChildNode(root.left);
int right = countChildNode(root.right);
map.put(root, left+right+1);
return left+right+1;
}
public void helper (TreeNode root, int k)
{
if(root == null)
{
return;
}
// 对于每个节点 node 就可以通过 node.left 推导出 node 的排名
int current;
if(root.left == null)
{
//root.left == null 说明当前root就是最左边的,就是第一。
current = 1;
}else
{
current = map.get(root.left)+1;
}
if(k == current)
{
result = root.val;
return;
}
// k is in the right tree of the current
if(k > current)
{
helper(root.right, k-current);
}
// k is in the left tree of the current
if(k < current)
{
helper(root.left, k);
}
}
}