leetcode 230. Kth Smallest Element in a BST-递归|非递归

原题链接:230. Kth Smallest Element in a BST

【思路-Java、Python】——递归实现

我们知道二分查找数(BST)的性质——任何一个节点的值均大于左子树的任意节点值,而小于右子树的任一节点值。那么这样就可以知道最小值的一个节点在树的最左端,最大值的一个节点在树的最右端。树从小到大顺序刚好满足树的中序遍历。因而,我们可以用中序遍历来处理。

由于 k 是个基本类型的数,我们知道它与应用类型不同,本轮递归的 k 值改变不会引起下一轮的改变,那么我们的处理办法可以增加一个全局变量、增加一个引用变量或增加一个方法形参,用这样的参数记录目前遍历到的是第几小的数,本题采用增加一个局部变量的方法:

public class Solution {
    private int count, res;
    public int kthSmallest(TreeNode root, int k) {
        if (root.left != null) kthSmallest(root.left, k);
        if (++count == k) res = root.val;     //①
        if (root.right != null) kthSmallest(root.right, k);
        return res;
    }
}
91 / 91  test cases passed. Runtime: 1 ms  Your runtime beats 46.33% of javasubmissions.

class Solution(object):
    def kthSmallest(self, root, k):
        """
        :type root: TreeNode
        :type k: int
        :rtype: int
        """
        global res, count
        res,count = 0,0
        def dfs(root, k) :
            if not root : return
            dfs(root.left, k)
            global count, res
            count += 1
            if count == k : res = root.val  //①
            dfs(root.right, k)
        dfs(root,k)
        return res
91 / 91  test cases passed. Runtime: 100 ms  Your runtime beats 25.55% of pythonsubmissions.

【思路-Java、Python】——非递归实现

非递归实现需要用到一个栈,如果对非递归和递归遍历实现不是很熟悉可以参考我的另外一篇博文: 

leetcode 94. Binary Tree Inorder Traversal leetcode 144. Binary Tree Preorder Traversal

上面有详细的介绍:

public class Solution {
    public int kthSmallest(TreeNode root, int k) {
        int ret = 0;
        Stack stack = new Stack();
        while(true) {
            while(root != null) {
                stack.push(root);
                root = root.left;
            }
            if (stack.isEmpty()) break;
            root = stack.pop();
            if (--k == 0) return root.val;  //②
            root = root.right;
        }
        return 0;
    }
91 / 91  test cases passed. Runtime: 2 ms  Your runtime beats 16.50% of javasubmissions.

class Solution(object):
    def kthSmallest(self, root, k):
        """
        :type root: TreeNode
        :type k: int
        :rtype: int
        """
        stack = []
        res = 0
        while 1 :
            while root :
                stack.append(root)
                root = root.left
            if not stack : break
            root = stack.pop()
            k -= 1
            if k == 0 : return root.val  //②
            root = root.right
        return 0
91 / 91  test cases passed. Runtime: 84 ms  Your runtime beats 72.03% of pythonsubmissions.

就时间复杂度而言,时间复杂度的对比,通过本题递归和非递归的对比,我们可以简单看出递归和非递归的区别。在递归中,我们不能“终止递归”,即使采用 return也无法终止递归,为此,采用递归必须遍历完每个节点,为此我们采用①记录找到的那个节点,时间复杂度为O(n)。而非递归不同,如果找到了第 k 大的那个节点我们就直接用② return返回了。我们可以看到递归效率不一定比非递归低,如本题。实际上空间复杂度,忽略方法的压栈等操作,并且临时变量能被立即释放的话,递归的空间复杂度还更低。

本题的基础还是树的递归和非递归:

leetcode 94. Binary Tree Inorder Traversal leetcode 144. Binary Tree Preorder Traversal

你可能感兴趣的:(LeetCode)