230 Kth Smallest Element in a BST

本文介绍了三种求解二叉搜索树中第K小元素的方法:迭代中序遍历、递归中序遍历及最优的二分查找法。通过代码实现详细解析了每种方法,并分析了其时间复杂度。

Given a binary search tree, write a function kthSmallest to find the kth smallest element in it. Note: You may assume k is always valid, 1 ≤ k ≤ BST's total elements.

这题是看到98. Validate Binary Search Tree 的一个非常好的summary里面这样写的。对于k的边界,考虑极端的,k=1就比较容易确定了。

DFS in-order iterative:

    public int kthSmallest(TreeNode root, int k) {
        Stack<TreeNode> stack = new Stack<>();
        while (root != null || !stack.isEmpty()) {
            while (root != null) {
                stack.push(root);
                root = root.left;
            }
            root = stack.pop();
            k--;
            if (k == 0) return root.val;
            root = root.right;
        }
        return -1;
    }
复制代码

因为是inorder traverse,这么看,时间复杂度是O(n)。 这题还有其他两种方法,明天写。

Mar 26

微风习习阳光和煦的周日。开始。 刚才百度了一下,dfs跟递归其实是不是一回事。dfs>递归,递归是dfs的一种手段,比如上面的stack就是非递归的、iterative 的dfs。

DFS in-order recursive

试着写了一下DFS in-order recursive,很接近答案了,尤其覃超说的 inoder就把递归放前后,中间写东西。所以把

        count--;
        if (count == 0) {
            res = root.val;
        }
复制代码

这段放中间。我犯的错误是,recursion函数中又带上了k这个参数,导致count--又带入了recursion。

略微修改后的AC代码:

public class Solution {
        int res, count;
    public int kthSmallest(TreeNode root, int k) {
        count = k;
        recursion(root);
        return res;
    }

    private void recursion(TreeNode root) {
        if (root == null) return;
        recursion(root.left);
        count--;
        if (count == 0) {
            res = root.val;
        }
        recursion(root.right);
    }
}
复制代码

这种的时间复杂度不知该怎么分析。。感觉是O(n)呢。空间复杂度是栈的复杂度,大概也是O(n)吧。

Binary Search (dfs): most preferable

最后一种也是复杂度最优的方法(讲解可以参考:http://blog.youkuaiyun.com/sunao2002002/article/details/46726245),非常容易懂。

首先计算左子树node的个数left

  1. 若left + 1 == k ,则root.val就是kth smallest
  2. 若left + 1 > k , 则kth smallest在左子树中
  3. 若left + 1 < k ,则转换为在右子树中,寻找第K-left-1(去除左子树和root node)个元素。

时间复杂度O(logn)。

    public int kthSmallest(TreeNode root, int k) {
        int left = countNode(root.left);
        if(left + 1 == k ) return root.val ;
        else if(left + 1 > k ) return kthSmallest(root.left , k);
        else return kthSmallest(root.right , k - left - 1);
    }

    private int countNode(TreeNode root) {
        //这里return 的应该是0 。用root只有一个node的情形考虑就行了。
        if (root == null) return 0;
        return 1 + countNode(root.left) + countNode(root.right);
    }
复制代码

这代码一次AC了,有点开心。

转载于:https://juejin.im/post/5a3132fd51882533d02310c2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值