📅  最后修改于: 2023-12-03 14:54:56.256000             🧑  作者: Mango
平衡二叉搜索树(Balanced Binary Search Tree,简称BBST)是一种特殊的二叉搜索树,它具有以下几个属性:
因为平衡二叉搜索树的这些属性,它在插入、删除、查询等操作中的时间复杂度是O(log n)的,而不需要在最坏情况下变成链表时的O(n)时间复杂度。
常见的平衡二叉搜索树实现方式包括:
问题描述:给定一棵二叉搜索树,请找出其中第k小的元素。
二叉搜索树的中序遍历是有序的,所以可以先进行中序遍历,然后找到第k小的元素即可。时间复杂度为O(n),空间复杂度为O(n),其中n是二叉搜索树中的节点数。
class Solution:
def kthSmallest(self, root: TreeNode, k: int) -> int:
def inorder(node):
if not node:
return []
return inorder(node.left) + [node.val] + inorder(node.right)
return inorder(root)[k-1]
class Solution {
public int kthSmallest(TreeNode root, int k) {
List<Integer> inorder = inorderTraversal(root);
return inorder.get(k-1);
}
private List<Integer> inorderTraversal(TreeNode node) {
List<Integer> res = new ArrayList<>();
if (node == null) {
return res;
}
res.addAll(inorderTraversal(node.left));
res.add(node.val);
res.addAll(inorderTraversal(node.right));
return res;
}
}
由于题目要求的是第k小的元素,我们可以在遍历过程中提前终止,不必继续遍历整棵树。时间复杂度可以降低到O(k),空间复杂度仍然是O(n)。
class Solution:
def kthSmallest(self, root: TreeNode, k: int) -> int:
def inorder(node):
if not node or len(res) == k:
return
inorder(node.left)
if len(res) == k:
return
res.append(node.val)
inorder(node.right)
res = []
inorder(root)
return res[-1]
class Solution {
public int kthSmallest(TreeNode root, int k) {
List<Integer> res = new ArrayList<>();
inorderTraversal(root, res, k);
return res.get(k-1);
}
private void inorderTraversal(TreeNode node, List<Integer> res, int k) {
if (node == null || res.size() == k) {
return;
}
inorderTraversal(node.left, res, k);
if (res.size() == k) {
return;
}
res.add(node.val);
inorderTraversal(node.right, res, k);
}
}
我们可以使用一个小根堆来维护当前遍历到的k个最小的元素。遍历完所有节点后,堆顶元素就是第k小的元素。时间复杂度为O(n log k),空间复杂度为O(k)。
class Solution:
def kthSmallest(self, root: TreeNode, k: int) -> int:
heap = []
def inorder(node):
if not node:
return
if len(heap) < k:
heapq.heappush(heap, -node.val)
else:
if node.val < -heap[0]:
heapq.heappushpop(heap, -node.val)
inorder(node.left)
inorder(node.right)
inorder(root)
return -heap[0]
class Solution {
public int kthSmallest(TreeNode root, int k) {
PriorityQueue<Integer> heap = new PriorityQueue<>();
inorderTraversal(root, heap, k);
return heap.peek();
}
private void inorderTraversal(TreeNode node, PriorityQueue<Integer> heap, int k) {
if (node == null) {
return;
}
if (heap.size() < k) {
heap.offer(node.val);
} else {
if (node.val > heap.peek()) {
heap.poll();
heap.offer(node.val);
}
}
inorderTraversal(node.left, heap, k);
inorderTraversal(node.right, heap, k);
}
}