题目
给定一个二叉搜索树,编写一个函数 kthSmallest 来查找其中第 k 个最小的元素。
说明:
你可以假设 k 总是有效的,1 ≤ k ≤ 二叉搜索树元素个数。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/kth-smallest-element-in-a-bst
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
分析
从本质来说其实就是二叉树的中序遍历,因为二叉搜索树的中序遍历结果就是从小到大排列的。
代码
方法1:直接中序遍历,输出整棵树的遍历结果,然后返回第k大的元素
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def kthSmallest(self, root, k):
"""
:type root: TreeNode
:type k: int
:rtype: int
"""
if root is None or k == 0:
return False
listNode = self.midOrder(root)
return listNode[k - 1]
def midOrder(self, root):
res = []
if root is None:
return []
if root.left:
res += self.midOrder(root.left)
if root and root.val is not None:
res.append(root.val)
if root.right:
res += self.midOrder(root.right)
return res
为了进一步节省时间和空间,一方面不需要对树整颗遍历,另外也不要保存所有的节点:
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def kthSmallest(self, root, k):
"""
:type root: TreeNode
:type k: int
:rtype: int
"""
if root is None or k == 0:
return False
target, k = self.midOrderK(root, k)
return target
def midOrderK(self, root, k): # 输入树的根节点和遍历到第几大了,k是递减的
# 相当于一个flag,当==1的时候,这个target 不为空了,也就用来存储结果
target = None
# 如果还没有遍历大第K小,那么target仍然为None
if root.left:
target, k = self.midOrderK(root.left, k)
# target 为None:
# 1. k==1, 下一个就是,那 target 就不再为 None
# 2. k!=1, k递减
if target is None and root is not None:
# 当遍历到某一个结点为目标结点时,后面所有的递归都依次因为target判断而退出
if k==1:
target = root.val
else:
k -=1
# target 仍然为 None, 遍历右子树
if target is None and root.right:
target, k = self.midOrderK(root.right, k)
return target, k