1. 程式人生 > 實用技巧 >[LeetCode] 1586. Binary Search Tree Iterator II

[LeetCode] 1586. Binary Search Tree Iterator II

Implement theBSTIteratorclass that represents an iterator overthein-order traversalofa binary search tree (BST):

  • BSTIterator(TreeNode root)Initializes an object of theBSTIteratorclass. Therootof the BST is given as part of the constructor. The pointer should be initialized to a non-existent number smaller than any element in the BST.
  • boolean hasNext()Returnstrueif there exists a number in the traversal to the right of the pointer, otherwise returnsfalse.
  • int next()Moves the pointer to the right, then returns the number at the pointer.
  • boolean hasPrev()Returnstrueif there exists a number in the traversal to the left of the pointer, otherwise returnsfalse
    .
  • int prev()Moves the pointer to the left, then returns the number at the pointer.

Notice that by initializing the pointer to a non-existent smallest number, the first call tonext()will return the smallest element in the BST.

You may assume thatnext()andprev()calls will always be valid. That is, there will be at least a next/previous number in the in-order traversalwhennext()

/prev()is called.

Follow up:Could you solve the problem without precalculating the values of the tree?

Example 1:

Input
["BSTIterator", "next", "next", "prev", "next", "hasNext", "next", "next", "next", "hasNext", "hasPrev", "prev", "prev"]
[[[7, 3, 15, null, null, 9, 20]], [null], [null], [null], [null], [null], [null], [null], [null], [null], [null], [null], [null]]
Output
[null, 3, 7, 3, 7, true, 9, 15, 20, false, true, 15, 9]

Explanation
// The underlined element is where the pointer currently is.
BSTIterator bSTIterator = new BSTIterator([7, 3, 15, null, null, 9, 20]); // state is  [3, 7, 9, 15, 20]
bSTIterator.next(); // state becomes [3, 7, 9, 15, 20], return 3
bSTIterator.next(); // state becomes [3, 7, 9, 15, 20], return 7
bSTIterator.prev(); // state becomes [3, 7, 9, 15, 20], return 3
bSTIterator.next(); // state becomes [3, 7, 9, 15, 20], return 7
bSTIterator.hasNext(); // return true
bSTIterator.next(); // state becomes [3, 7, 9, 15, 20], return 9
bSTIterator.next(); // state becomes [3, 7, 9, 15, 20], return 15
bSTIterator.next(); // state becomes [3, 7, 9, 15, 20], return 20
bSTIterator.hasNext(); // return false
bSTIterator.hasPrev(); // return true
bSTIterator.prev(); // state becomes [3, 7, 9, 15, 20], return 15
bSTIterator.prev(); // state becomes [3, 7, 9, 15, 20], return 9

Constraints:

  • The number of nodes in the tree is in the range[1, 105].
  • 0 <= Node.val <= 106
  • At most 105calls will be made tohasNext,next,hasPrev, andprev.

二叉搜尋樹迭代器II。題目是173題的版本二,題設差不多,也是遍歷BST,但是本題需要額外輸出一個prev,既中序遍歷的前一個節點。同時本題的followup是問你能否不提前遍歷樹中的值來解決問題。

既然是遍歷二叉搜尋樹那麼一定還是逃不掉中序遍歷的思想。但是這道題的followup是問能否不提前遍歷,所以我們可以一邊遍歷一邊得出需要的值,同時用一個list存住已經遍歷過的值。具體的做法是,首先先按照中序遍歷的前半段,不斷地把當前節點入棧,並一直往左子樹走,直到走到最小的左子節點位為止。

hasNext()函式問的是當前節點之後是否還有節點,我們一般判斷的邏輯是stack是否為空,但是本題我們可以先判斷下一個節點是否已經被儲存在list中了(因為題目會反覆問你prev和next是否存在),如果不在,再判斷stack是否為空。

next()函式,如果list中存在index + 1,則輸出這個節點值;如果如果list中不存在index + 1,但是hasNext()為true的話,就說明下一個節點還未從stack中彈出,我們把它從stack中彈出並且加入list。記得index++。

hasPrev()和prev()就比較簡單了,因為是往前看,所以直接去判斷inRange是否合法和去list裡面找相應index即可。

時間O(n)

空間O(n)

Java實現

 1 /**
 2  * Definition for a binary tree node.
 3  * public class TreeNode {
 4  *     int val;
 5  *     TreeNode left;
 6  *     TreeNode right;
 7  *     TreeNode() {}
 8  *     TreeNode(int val) { this.val = val; }
 9  *     TreeNode(int val, TreeNode left, TreeNode right) {
10  *         this.val = val;
11  *         this.left = left;
12  *         this.right = right;
13  *     }
14  * }
15  */
16 class BSTIterator {
17     Stack<TreeNode> stack = new Stack<>();
18     List<TreeNode> list = new ArrayList<>();
19     int index = -1;
20 
21     private void pushLeft(TreeNode root) {
22         while (root != null) {
23             stack.push(root);
24             root = root.left;
25         }
26     }
27 
28     private boolean inRange(int i) {
29         return i >= 0 && i < list.size();
30     }
31 
32     public BSTIterator(TreeNode root) {
33         pushLeft(root);
34     }
35 
36     public boolean hasNext() {
37         if (inRange(index + 1)) {
38             return true;
39         }
40         return !stack.isEmpty();
41     }
42 
43     public int next() {
44         int nextVal = 0;
45         if (inRange(index + 1)) {
46             nextVal = list.get(index + 1).val;
47         } else {
48             TreeNode next = stack.pop();
49             pushLeft(next.right);
50             list.add(next);
51             nextVal = next.val;
52         }
53         index++;
54         return nextVal;
55     }
56 
57     public boolean hasPrev() {
58         return inRange(index - 1);
59     }
60 
61     public int prev() {
62         return list.get(--index).val;
63     }
64 }
65 
66 /**
67  * Your BSTIterator object will be instantiated and called as such:
68  * BSTIterator obj = new BSTIterator(root);
69  * boolean param_1 = obj.hasNext();
70  * int param_2 = obj.next();
71  * boolean param_3 = obj.hasPrev();
72  * int param_4 = obj.prev();
73  */

相關題目

173. Binary Search Tree Iterator

1586. Binary Search Tree Iterator II

LeetCode 題目總結