题目
实现一个二叉搜索树迭代器。你将使用二叉搜索树的根节点初始化迭代器。
调用 next()
将返回二叉搜索树中的下一个最小的数。
注意: next()
和hasNext()
操作的时间复杂度是O(1),并使用 O(h)内存,其中 h是树的高度。
原题地址:https://leetcode.com/problems/binary-search-tree-iterator/
解题思路
- 如果不看「注意」,我们很容易想到的是,先利用中序遍历将二叉树从大到小 遍历一遍放入一个栈中,然后利用栈的
pop()
和isEmpty()
方法实现题目,但是这个「注意」中强调时间复杂度和空间复杂度的问题,遍历的方法满足时间复杂度,但是不满足空间复杂度。这里奇怪的是,我利用以上方法提交解答的时候居然显示通过 ,可能是leetcode哪出问题了2333.
- 所以我们应该考虑空间复杂度的问题,题目要求使用O(h)内存,首先可以将二叉树最左边的所有结点入栈,然后每次出栈一个,判断其是否有右子树,如果有,就再将右子树为根的最左边所有结点入栈,这样可以保持使用O(h)的内存。
解题代码
1.不合题意的做法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
|
public class BSTIterator { private Stack<Integer> stack = new Stack<Integer>(); public BSTIterator(TreeNode root) { inOrder(root); }
public boolean hasNext() { return !stack.isEmpty(); }
public int next() { return stack.pop(); } public void inOrder(TreeNode root){ if(root != null) { inOrder(root.right); stack.push(root.val); inOrder(root.left); } } }
|
提交结果
1 2 3
| 61 / 61 个通过测试用例 状态:通过 执行用时:16 ms
|
2.正解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
|
public class BSTIterator {
private Stack<TreeNode> stack ; public BSTIterator(TreeNode root) { this.stack = new Stack<>(); dfs(root); }
private void dfs(TreeNode root) { while (root!=null){ stack.push(root); root = root.left; } }
public boolean hasNext() { return !stack.empty(); }
public int next() { TreeNode pop = stack.pop(); dfs(pop.right); return pop.val; }
}
|
提交结果:
1 2 3
| 61 / 61 个通过测试用例 状态:通过 执行用时:5 ms
|