1、二叉搜索树迭代器
实现一个二叉搜索树迭代器。你将使用二叉搜索树的根节点初始化迭代器。
调用 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 ms | 48.1 MB | Java |
居然击败了99.03%的java提交,有点意外(