题目描述:
给定一个二叉搜索树的根节点 root ,和一个整数 k ,请你设计一个算法查找其中第 k 个最小元素(从 1 开始计数)。
示例:
输入:root = [3,1,4,null,2], k = 1
输出:1
输入:root = [5,3,6,2,4,null,null,1], k = 3
输出:3
思路1: 中序遍历得到有序排列,取第k小
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution(object):
def kthSmallest(self, root, k):
"""
:type root: TreeNode
:type k: int
:rtype: int
"""
result = []
self.inorder(root, result)
return result[k-1]
def inorder(self, root, result):
if not root:
return
self.inorder(root.left, result)
result.append(root.val)
self.inorder(root.right, result)
时间复杂度为O(H+K),H为树的高度;空间复杂度为O(H)。
思路2: 主要是针对进阶1:如果需要频繁地查找第 k 小的值,你将如何优化算法?
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution(object):
def __init__(self):
self.dict = {}
def kthSmallest(self, root, k):
"""
:type root: TreeNode
:type k: int
:rtype: int
"""
# 另一种思路,存放每个结点的以其为根的结点总数量
# 从根节点开始,如果当前的k值小于左子树的结点的数量,则从右子树开始遍历,等等
# 在统计每个节点的数量的时候,可以采用递归的方式
self.count(root)
return self.k(root, k)
def k(self, root, k):
if k-1 == self.search_num(root.left):
return root.val
if k-1 < self.search_num(root.left):
return self.k(root.left, k)
if k-1 > self.search_num(root.left):
return self.k(root.right, k-self.search_num(root.left)-1)
def count(self, root):
if not root:
return 0
self.dict[root] = 1 + self.count(root.left) + self.count(root.right)
return self.dict[root]
def search_num(self, root):
if root in self.dict.keys():
return self.dict[root]
else:
return 0
时间复杂度为O(n),空间复杂度为O(n)。
思路3: 考虑树中会不断的插入、删除,并且要频繁的访问第k个元素的情况,这个时候可以采取的思路是,转换成平衡二叉树,然后继续做,具体地,详见官方的题解。
点击此处得到对应的链接