📅  最后修改于: 2023-12-03 15:21:30.685000             🧑  作者: Mango
二叉搜索树(Binary Search Tree,BST)是一种常见的数据结构,它是一个有序的二叉树,其中每个节点的值都大于其左子树中任意节点的值,小于其右子树中任意节点的值。在一个BST中,第K个最大元素是一种常见的需求,下面介绍三种解决方案。
第一种解决方案是使用递归方法。通过中序遍历BST,将元素按照从大到小的顺序排列。则第K个最大元素即为中序遍历序列的第K个元素。
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
def kthLargest(self, root: TreeNode, k: int) -> int:
self.result = None
self.k = k
self.helper(root)
return self.result
def helper(self, node):
if node is None:
return
self.helper(node.right)
self.k -= 1
if self.k == 0:
self.result = node.val
return
self.helper(node.left)
第二种解决方案是使用迭代方法,使用栈来模拟中序遍历BST的过程。通过将元素按照从大到小的顺序压入栈中,第K个最大元素即为栈中的第K个元素。
class Solution:
def kthLargest(self, root: TreeNode, k: int) -> int:
stack = []
node = root
while stack or node:
while node:
stack.append(node)
node = node.right
node = stack.pop()
k -= 1
if k == 0:
return node.val
node = node.left
第三种解决方案是使用Morris遍历,可以不用栈和递归来实现中序遍历。该算法使用线索树的思想,将每个节点的right指针指向它的后继,将每个节点的left指针指向它的前驱。具体过程可以查看这篇文章。
class Solution:
def kthLargest(self, root: TreeNode, k: int) -> int:
node = root
while node:
if node.right is None:
k -= 1
if k == 0:
return node.val
node = node.left
else:
pre = node.right
while pre.left and pre.left != node:
pre = pre.left
if pre.left is None:
pre.left = node
node = node.right
else:
pre.left = None
k -= 1
if k == 0:
return node.val
node = node.left
以上三种解决方案中,第一种和第二种都需要O(n)的时间和空间复杂度,其中n为BST中节点的个数。第三种方法只需要O(h)的空间复杂度,其中h为BST的高度,但是最坏情况下时间复杂度仍然是O(n)。