题目
leetcode 230. 二叉搜索树中第K小的元素 的三种解法:优先队列;中序遍历;中序遍历+统计子树节点
解法一:优先队列
/**
* 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 {
public int kthSmallest(TreeNode root, int k) {
PriorityQueue<Integer> pq = new PriorityQueue<>();
dfs(root, pq);
int res = pq.peek();
for (int i = 0; i < k; i++) res = pq.poll();
return res;
}
private void dfs(TreeNode root, PriorityQueue<Integer> pq) {
if (root == null) return;
pq.add(root.val);
dfs(root.left, pq);
dfs(root.right, pq);
}
}
- 默认为小根堆,不用重写 Comparator
- 时间复杂度:O(H*logn + k),H 为树的高度,取值为[logn, n]
- 空间复杂度:O(n)
解法二:中序遍历
class Solution {
public int kthSmallest(TreeNode root, int k) {
ArrayDeque<TreeNode> stack = new ArrayDeque<>();
while (!stack.isEmpty() || root != null) {
while (root != null) {
stack.push(root);
root = root.left;
}
root = stack.pop();
k--;
if (k == 0) break;
root = root.right;
}
return root.val;
}
}
- 时间复杂度:O(H + k)
- 空间复杂度:O(H)
解法三:中序遍历+统计子树节点数
- 若左子树节点总数小于 k ,则所求节点必在右子树
class Solution {
public int kthSmallest(TreeNode root, int k) {
int lcnt = countNodes(root.left);
if (lcnt == k-1) return root.val;
else if (lcnt < k-1) return kthSmallest(root.right, k-lcnt-1);
else return kthSmallest(root.left, k);
}
private int countNodes(TreeNode root) {
if (root == null) return 0;
return countNodes(root.left) + countNodes(root.right) + 1;
}
}
- 时间复杂度:O(H)
- 空间复杂度:O(H)