Leetcode: 230. 二叉搜索树中第K小的元素

33 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第12天,点击查看活动详情

230. 二叉搜索树中第K小的元素

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/kt…

给定一个二叉搜索树的根节点 root ,和一个整数 k ,请你设计一个算法查找其中第 k 个最小元素(从 1 开始计数)。

在这里插入图片描述

示例 1:

输入:root = [3,1,4,null,2], k = 1 输出:1

在这里插入图片描述

示例 2:

输入:root = [5,3,6,2,4,null,null,1], k = 3 输出:3

提示:

  • 树中的节点数为 n 。
  • 1<=k<=n<=1041 <= k <= n <= 10^4
  • 0<=Node.val<=1040 <= Node.val <= 10^4

进阶:如果二叉搜索树经常被修改(插入/删除操作)并且你需要频繁地查找第 k 小的值,你将如何优化算法?

解法

  • 方法:二叉搜索树,左边节点严格小于根节点,根节点严格小于右节点,按照中序遍历左根右得到从小到大排序。

  • python

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def kthSmallest(self, root: TreeNode, k: int) -> int:
        # 中序遍历
        if root is None:
            return None
        def help(root):
            if root == None:
               return []
            res = []
            res += help(root.left)
            res.append(root.val)
            res += help(root.right)
            return res
        res = help(root)
        return res[k-1]
  • c++
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    int kthSmallest(TreeNode* root, int k) {
        stack<TreeNode *> stack;
        while (root != nullptr || stack.size() > 0)
        {
            while (root != nullptr) {
                stack.push(root);
                root = root->left;
            }
            root = stack.top();
            stack.pop();
            --k;
            if(k==0)
            {
                break;
            }
            root = root->right;
        }
        return root->val;
    }
};

复杂度分析

  • 时间复杂度:O(H+k),其中 H 是树的高度。在开始遍历之前,我们需要 O(H) 到达叶结点。当树是平衡树时,时间复杂度取得最小值 O(logN+k);当树是线性树(树中每个结点都只有一个子结点或没有子结点)时,时间复杂度取得最大值 O(N+k)

  • 空间复杂度:O(H),栈中最多需要存储 H 个元素。当树是平衡树时,空间复杂度取得最小值 O(logN);当树是线性树时,空间复杂度取得最大值 O(N)