版权声明:本文为博主原创文章,未经博主允许不得转载。有事联系:[email protected] https://blog.csdn.net/qq_17550379/article/details/82423465
给定一个二叉搜索树,编写一个函数 kthSmallest
来查找其中第 k 个最小的元素。
说明:
你可以假设 k 总是有效的,1 ≤ k ≤ 二叉搜索树元素个数。
示例 1:
输入: root = [3,1,4,null,2], k = 1
3
/ \
1 4
\
2
输出: 1
示例 2:
输入: root = [5,3,6,2,4,null,null,1], k = 3
5
/ \
3 6
/ \
2 4
/
1
输出: 3
进阶:
如果二叉搜索树经常被修改(插入/删除操作)并且你需要频繁地查找第 k 小的值,你将如何优化 kthSmallest
函数?
解题思路
我们首先想到的方法是对这个树排序,然后取第k
小的元素即可。但是怎么对一颗树排序呢?遍历一棵树,然后将遍历的结果存在一个list
里面,然后对这个list
排序。我们要解决的问题就是如何遍历一颗树
Leetcode 144:二叉树的前序遍历(最优雅的解法!!!)
Leetcode 94:二叉树的中序遍历(最优雅的解法!!!)
Leetcode 145:二叉树的后序遍历(最详细的解法!!!)
我这里以前序遍历为例,写出如下操作
class Solution:
def kthSmallest(self, root, k):
"""
:type root: TreeNode
:type k: int
:rtype: int
"""
result = list()
stack = [root]
while len(stack):
top = stack.pop()
if top.right:
stack.append(top.right)
if top.left:
stack.append(top.left)
result.append(top.val)
result.sort()
return result[k-1]
但是有没有更快地算法呢?有没有办法,在遍历的过程中就知道list
的排序呢?啊!!!中序遍历
。我们知道中序遍历
的结果是一个有序的list
,所以我们可以在中序遍历中设置提前停止。
class Solution:
def _inOrder(self, root, arr, k):
if root:
self._inOrder(root.left, arr, k)
if len(arr) >= k:
return
arr.append(root.val)
self._inOrder(root.right, arr, k)
def kthSmallest(self, root, k):
"""
:type root: TreeNode
:type k: int
:rtype: int
"""
result = list()
self._inOrder(root, result, k)
return result[k - 1]
同样的,对于递归可以解决的问题,我都希望可以通过迭代去解决。这个问题很容易,也就是写出中序遍历的迭代形式。
class Solution:
def kthSmallest(self, root, k):
"""
:type root: TreeNode
:type k: int
:rtype: int
"""
result = list()
stack = list()
while stack or root:
if root:
stack.append(root)
root = root.left
else:
root = stack.pop()
result.append(root.val)
if len(result) >= k:
break
root = root.right
return result[k-1]
我将该问题的其他语言版本添加到了我的GitHub Leetcode
如有问题,希望大家指出!!!