Kth Smallest Element in a BST 找二叉搜索树中的第k小的元素

一个容易想到的想法是基于二叉树,只要对二叉树进行中序遍历,序列中第k个元素就是想要找的第k小的元素。

在这里,我还会介绍另一解法。基于binar search的,这个方法的效率更高。

解法1:中序遍历。

中序遍历可以通过递归的方式,也可以通过迭代的方式。

基本思想就是当我已经输出到第k个元素了,我就可以直接返回这个元素了,后面的遍历不需要再进行了。

代码:就是在之前的中序遍历上进行修改,不需要存储结果的list。

而是设置一个k变量,每次输出一个树就-1,当k = 0时候,返回遍历到的元素。

代码:

    public int kthSmallestByInOrderIterative(TreeNode root, int k) {
        Stack<TreeNode> store = new Stack<>();
        if (root == null) {
            return -1;
        }
        store.push(root);
        while (root.left != null) {
            store.push(root.left);
            root = root.left;
        }
        while (!store.empty()) {
            TreeNode cur = store.pop();
            k--;
            if (k == 0) {
                return cur.val;
            }
            if (cur.right != null) {
                root = cur.right;// let cur.right be the current node
                store.push(root);
                while (root.left != null) {
                    store.push(root.left);
                    root = root.left;
                }
            }
        }
        return -1;
    }

解法2:binary seach

二分的思想是我每次看看当前节点的左子树中有多少个元素,记为count。

如果我的k <= count,那么显然第k小的树在左子树中,在左子树中继续进行二分搜索。

如果我的k == count + 1, 那么当前节点恰好是这个第k小的节点,直接返回节点点。

如果我的k > count + 1, 那么第k小的节点在右子树,在右子树中继续进行二分搜索。


代码:

    public int kthSmallestByBinarySearch(TreeNode root, int k) {
        int count = countNum(root.left);
        if (k == count + 1) {
            return root.val;
        } else if (k <= count) {
            return kthSmallestByBinarySearch(root.left, k);
        } else {
            return kthSmallestByBinarySearch(root.right, k - 1 - count);// count is the left tree num, 1 is the root
        }
    }

    private int countNum(TreeNode node) {
        if (node == null) {
            return 0;
        }
        return 1 + countNum(node.left) + countNum(node.right);
    }


参考资料:

https://leetcode.com/discuss/43771/implemented-java-binary-search-order-iterative-recursive

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值