230. Kth Smallest Element in a BST

Given a binary search tree, write a function kthSmallest to find the kth smallest element in it.

Note: 
You may assume k is always valid, 1 ≤ k ≤ BST's total elements.

Example 1:

Input: root = [3,1,4,null,2], k = 1
   3
  / 
 1   4
  
   2
Output: 1

Example 2:

Input: root = [5,3,6,2,4,null,null,1], k = 3
       5
      / 
     3   6
    / 
   2   4
  /
 1
Output: 3

Follow up:
What if the BST is modified (insert/delete operations) often and you need to find the kth smallest frequently? How would you optimize the kthSmallest routine?

M1: dfs recursion + inorder traversal

time: O(n), space: O(n)

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    int cnt;
    int res = 0;
    
    public int kthSmallest(TreeNode root, int k) {
        cnt = k;
        inorder(root);
        return res;
    }
    
    private void inorder(TreeNode root) {
        if(root == null) {
            return;
        }
        inorder(root.left);
        cnt--;
        if(cnt == 0) {
            res = root.val;
            return;
        }
        inorder(root.right);
    }
}

M2: binary search + dfs (optimal)

先对root的左子节点递归调用辅助函数求节点个数count,如果k <= count 说明第k小的元素在左子树里,如果k > count + 1 说明在右子树里,如果count = k + 1 说明当前节点就是第k小的元素,直接返回就行

time: O(h), space: O(h)

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public int kthSmallest(TreeNode root, int k) {
        if(root == null) {
            return 0;
        }
        int cnt = countNodes(root.left);
        if(k <= cnt) {
            return kthSmallest(root.left, k);
        } else if(k > cnt + 1) {
            return kthSmallest(root.right, k - cnt - 1);
        }
        return root.val;
    }
    
    public int countNodes(TreeNode node) {
        if(node == null) {
            return 0;
        }
        return 1 + countNodes(node.left) + countNodes(node.right);
    }
}

ref: https://leetcode.com/problems/kth-smallest-element-in-a-bst/discuss/63660/3-ways-implemented-in-JAVA-(Python)%3A-Binary-Search-in-order-iterative-and-recursive

原文地址:https://www.cnblogs.com/fatttcat/p/10231305.html