leetcode 230:二叉搜索树中第k小的元素

题目描述:
给定一个二叉搜索树的根节点 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个元素的情况,这个时候可以采取的思路是,转换成平衡二叉树,然后继续做,具体地,详见官方的题解。
点击此处得到对应的链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值