Given a binary search tree, write a function kthSmallest
to find the kth smallest element in it.
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?
思路:
BST的重要性质:中序遍历(inorder)BST的结果:值从小到大输出所有node
本题k的最小值为1.
解法1: 迭代+栈 解法2: 递归
解法1: 非递归 (iterativaly)
中序遍历: 用栈存储:
循环1:从头结点开始,循环2(一路向左把所有左结点压入栈中,当把最左侧的结点压进去后),pop栈顶元素,并把当前pop结点的右子树压入栈。直到栈为空。
由于要找第Kth小的结点的值,也就是第K次pop出来的结点,所以定义一个全局变量count = 0, 每次pop一个出来,count++, 当count == k的时候,return root.val
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
private int count = 0;
public int kthSmallest(TreeNode root, int k) {
return inorder(root, k);
}
private int inorder(TreeNode root, int k) {
Stack<TreeNode> s = new Stack<>();
while(root != null || !s.isEmpty()) {
while(root != null) {
s.add(root);
root = root.left;
}
root = s.pop();
if(++count == k) return root.val;
root = root.right;
}
// 没有找到(root == null || K < 1 || k > BST's total elements
.)
return -1;
}
}
解法二:递归法
中序遍历采用递归法,代码简介很多。如果有左子树就继续递归,否则就处理当前结点,再递归右子树。
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode() {} * TreeNode(int val) { this.val = val; } * TreeNode(int val, TreeNode left, TreeNode right) { * this.val = val; * this.left = left; * this.right = right; * } * } */ class Solution { private int count = 0; private int res = -1; public int kthSmallest(TreeNode root, int k) { inorder(root, k); return res; } private void inorder(TreeNode root, int k) { if(root.left != null) { inorder(root.left, k); } if(++count == k) { res = root.val; return; } if(root.right != null) { inorder(root.right, k); } } }