【问题标题】:Finding kthSmallestElement in the BST在 BST 中查找 kthSmallestElement
【发布时间】:2018-02-05 04:47:42
【问题描述】:

我正在尝试解决 LeetCode 的以下问题:

https://leetcode.com/problems/kth-smallest-element-in-a-bst/description/

目标是,给定一个 BST,我们必须找出其中第 K 个最小的元素并返回它的值。

我自己可以想出一个O(n) 时空解决方案。但是我在在线帮助下编写的另一个解决方案要好得多:

    /**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    int kthSmallestUtil(TreeNode* root, int& k) {
        if(!root) return -1;

        int value=kthSmallestUtil(root->left, k);
        if(!k) return value;

        k--;
        if(k==0) return root->val;

        return kthSmallestUtil(root->right, k);
    }

    int kthSmallest(TreeNode* root, int k) {
        return kthSmallestUtil(root, k);
    }
};

我已经了解上述解决方案。我也调试过(https://onlinegdb.com/BJnoIkrLM),在29、30、33、37处插入断点。不过还是有点不安,原因如下:

在调用kthSmallestUtil(root->left, k);的情况下,我们传递k的原始值;然后我们(可以理解地)减少当前根的k 的值(因为我们正在按顺序进行遍历)。但是,当我们再次对kthSmallestUtil(root->right, k); 进行递归时,为什么不传递k 的原始值呢?为什么正确的孩子会得到“优惠”待遇——k的递减值?

我知道因为调试k 的值是如何变化的,我们得到了最终的答案。但我正在寻找一些直觉背后使用k 的原始值作为左孩子和@987654333 的递减值@ 为正确的孩子。

【问题讨论】:

    标签: c++ binary-search-tree


    【解决方案1】:

    这个解决方案似乎假设一个有序的二叉搜索树。 这意味着树的左分支只包含比当前节点 val 更小的值。因此它首先递归到左分支,沿途递减 k,然后如果 k 不为 0,则为当前元素递减 k。如果 k 仍然不为 0,则考虑右分支中的值,均大于当前节点值。

    你需要了解的是k在k--中递减; line不是k的原始值,而是整个左分支遍历后k的值。

    递归调用都修改了相同的 k,因为 k 是通过引用而不是值传递的

    【讨论】:

    • 是的,所以我得到了 - 遍历整个左分支后 k 的值。假设遍历整个左分支后的值为k1。然后对于当前根,假设我们减少了k1 并得到了新值k2。现在,在进入正确的分支之前,为什么我们不递减k2(表示对当前节点(根)的遍历(或访问))?
    • k2 是您示例中的递减值。您自己感到困惑,认为当前根和当前节点是不同的东西。再次检查代码。它永远不会访问它自己的根。 root 变量存储当前节点,因此是 if(k==0) return root->val; 行。
    【解决方案2】:

    这样的代码工作量更少 - 尽可能深入 BST 的左分支。当你到达最左边的叶子 - 最小值 - 减少 k 值并开始在 BST 的剩余部分进行搜索。因为我们已经访问了整个树中的最小值并且我们正在搜索第 k 个最小值,所以我们必须在树的其余部分中搜索 k-1th 最小值(因为我们不再考虑最左边的叶子)。因此,如果k 等于零,则表示当前节点具有第 k 个最小值。否则,还需要搜索右子树。

    【讨论】:

    • 知道了。谢谢! :)
    • 所以基本上,我们进行“优先”处理,因为我们现在正在寻找k-1th 最小节点(已经访问了一个预期的最小节点)。我说的对吗?
    • @Ganpat 如果我猜对了 - 是的。我们在搜索中省略了最小元素,所以从其余元素中搜索k-1th minimum
    • 一个 qq —— 那么当我们通过当前根节点时,为什么我们不再次减小k 的值(基本上是k-2)?按照你的逻辑,既然我们已经消除了当前节点可能是目标(k!=0)的可能性,为什么我们在进入正确的孩子之前不再次递减k
    • 但是我们确实在k--的行中减少了当前根节点的k。我的意思是,每个节点都会为自己减小 k。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-26
    • 2014-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多