二叉树系列(一)

Posted by Lain on 09-23,2019

1、二叉搜索树迭代器

实现一个二叉搜索树迭代器。你将使用二叉搜索树的根节点初始化迭代器。

0
调用 next() 将返回二叉搜索树中的下一个最小的数。
示例:

BSTIterator iterator = new BSTIterator(root);
iterator.next();    // 返回 3
iterator.next();    // 返回 7
iterator.hasNext(); // 返回 true
iterator.next();    // 返回 9
iterator.hasNext(); // 返回 true
iterator.next();    // 返回 15
iterator.hasNext(); // 返回 true
iterator.next();    // 返回 20
iterator.hasNext(); // 返回 false

提示:

  • next() 和 hasNext() 操作的时间复杂度是 O(1),并使用 O(h) 内存,其中 h 是树的高度。
  • 你可以假设 next() 调用总是有效的,也就是说,当调用 next() 时,BST 中至少存在一个下一个最小的数。

emmm,这种题目算是考察二叉树基础,LeetCode把它归到中等难度里去了==
其实就是考察二叉树的遍历,以及栈的使用。
先来复习一下什么是二叉搜索树,资料来自百度百科:
二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树
简而言之,二叉查找树的最左边的子节点必定是最小值,把它中序遍历了就能直接得到一个从小到大排序的数组。不过我们这里是做一个迭代器,如果在初始化时先把它全遍历一遍装进数组里那也太蠢了,而且也不符合题目提示里关于内存的要求,因此我们需要一个栈结构来存储它的遍历历史,在next里出栈,以保证内存的占用不超过O(h)。
下面上代码:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class BSTIterator {

 Stack<TreeNode> stack = new Stack<>();
    public BSTIterator(TreeNode root) {
        if(root!=null){//有可能是空树,防止空指针异常
            this.stack.push(root);
            while (root.left!=null){//深度优先,将左子树所有左节点入栈
                this.stack.push(root.left);
                root= root.left;
            }
        }
        
    }

    /** @return the next smallest number */
    public int next() {
        TreeNode next = stack.pop();//出栈
        if(next == null){
            return -1;
        }
        if(next.right!=null){
            stack.push(next.right);//入栈右节点
            TreeNode left = next.right.left;//入栈右子树的所有左节点
            while(left!=null){
                stack.push(left);
                left = left.left;
            }

        }
        return next.val;
    }

    /** @return whether we have a next smallest number */
    public boolean hasNext(){
        return !stack.isEmpty();//栈不为空,则还有值
    }

}

提交时间提交结果执行用时内存消耗语言
20 分钟前通过80 ms48.1 MBJava

居然击败了99.03%的java提交,有点意外(