题目

Implement an iterator over a binary search tree (BST). Your iterator will be initialized with the root node of a BST.

Calling next() will return the next smallest number in the BST.

Example:

image.png

  1. BSTIterator iterator = new BSTIterator(root);
  2. iterator.next(); // return 3
  3. iterator.next(); // return 7
  4. iterator.hasNext(); // return true
  5. iterator.next(); // return 9
  6. iterator.hasNext(); // return true
  7. iterator.next(); // return 15
  8. iterator.hasNext(); // return true
  9. iterator.next(); // return 20
  10. iterator.hasNext(); // return false

Note:

  • next() and hasNext() should run in average O(1) time and uses O(h) memory, where h is the height of the tree.
  • You may assume that next() call will always be valid, that is, there will be at least a next smallest number in the BST when next() is called.

题意

实现一个BST迭代器,要求next()和hasNext()的平均时间复杂度为$O(1)$且空间复杂度为$O(h)$。

思路

如果没有复杂度限制,那么最简单的方法就是先一遍中序遍历将所有值记录下来,调用next()时挨个返回就行。空间复杂度为$O(h)$,做法就参考中序遍历的迭代实现:初始化时先将最左侧的边存储下来,每次调用next()时,栈顶元素就是下一个应返回的结点,出栈后将该结点右子树的最左侧边存入栈。重复上述过程,栈中元素数量最大为树高,且查询平均复杂度为$O(1)$。


代码实现

Java

  1. class BSTIterator {
  2. private Deque<TreeNode> stack;
  3. private int index;
  4. public BSTIterator(TreeNode root) {
  5. stack = new ArrayDeque<>();
  6. while (root != null) {
  7. stack.push(root);
  8. root = root.left;
  9. }
  10. }
  11. /**
  12. * @return the next smallest number
  13. */
  14. public int next() {
  15. TreeNode node = stack.pop();
  16. TreeNode tmp = node.right;
  17. while (tmp != null) {
  18. stack.push(tmp);
  19. tmp = tmp.left;
  20. }
  21. return node.val;
  22. }
  23. /**
  24. * @return whether we have a next smallest number
  25. */
  26. public boolean hasNext() {
  27. return !stack.isEmpty();
  28. }
  29. }

JavaScript

  1. /**
  2. * Definition for a binary tree node.
  3. * function TreeNode(val, left, right) {
  4. * this.val = (val===undefined ? 0 : val)
  5. * this.left = (left===undefined ? null : left)
  6. * this.right = (right===undefined ? null : right)
  7. * }
  8. */
  9. /**
  10. * @param {TreeNode} root
  11. */
  12. var BSTIterator = function (root) {
  13. this.stack = []
  14. while (root) {
  15. this.stack.push(root)
  16. root = root.left
  17. }
  18. }
  19. /**
  20. * @return {number}
  21. */
  22. BSTIterator.prototype.next = function () {
  23. let top = this.stack.pop()
  24. let p = top.right
  25. while (p) {
  26. this.stack.push(p)
  27. p = p.left
  28. }
  29. return top.val
  30. }
  31. /**
  32. * @return {boolean}
  33. */
  34. BSTIterator.prototype.hasNext = function () {
  35. return this.stack.length
  36. }