-
Notifications
You must be signed in to change notification settings - Fork 22
/
Inorder Successor in BST.java
executable file
·172 lines (144 loc) · 5.55 KB
/
Inorder Successor in BST.java
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
M
1533276962
tags: BST, Tree
找 Inorder traversal规则里的下一个.
主要想法是考虑:
1. 如果 node.right == null, 找上一个unprocessed node alone the inorder traversal path
2. 如果 node.right != null, successor 一定在这个node.right那个subtree里面
最后竟然可以简化成几行, 非常全面的BST问题: 有search, 有对inorder traversal的理解, 还有坑.
#### Short Recursive and Iterative without Stack
- Previous solution, we use stack to hold previous cached/unprocessed items: but do we need use catch to hold them?
- If moving left: `p.val < root.val`, then root (parent of left child) is a successor candidate, so save `rst = root`.
- If moving right or equal: `p.val >= root.val`, the successor has nothing to do with curr node, so just directly dive into root.right.
- Both iterative and recursive solution can be simplified as such.
#### Previous Iterative + stack
- Iteratively search
- Still need stack to store previously unprocessed items along the path
#### Previous Recursive + Stack
- 画inorder图,发现规律.每个node的后继node(successor)有几种情况:
- 1. node.right 是个leaf到底了。那么就return.
- 2. set rightNode = node.right, 但发现rightNode has a lot left children to leaf.
- 3. 比如, node.right == null, 也就是node自己是leaf,要回头看山顶找Inorder traversal规则里的下一个。
- 发现:其实就是每层都把路过的curr node放在stack里,最上面的,就是当下改return的那个successor:) Done.
```
/*
Given a binary search tree (See Definition) and a node in it, find the in-order successor of that node in the BST.
Have you met this question in a real interview? Yes
Example
Given tree = [2,1] and node = 1:
2
/
1
return node 2.
Given tree = [2,1,3] and node = 2:
2
/ \
1 3
return node 3.
Note
If the given node has no in-order successor in the tree, return null.
Challenge
O(h), where h is the height of the BST.
Tags Expand
Binary Search Tree Binary Tree
*/
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
// Short Recursive version:
class Solution {
public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
if (root == null) return root;
if (p.val < root.val) {
TreeNode left = inorderSuccessor(root.left, p);
return left != null ? left : root;
} else { // p.val >= root.val
return inorderSuccessor(root.right, p);
}
}
}
// Short Iterative version:
class Solution {
public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
TreeNode rst = null;
while (root != null) {
if (p.val < root.val) {
rst = root; // cache curr node as parent of left child
root = root.left;
} else { // p.val >= root.val
root = root.right;
}
}
return rst;
}
}
// Prev iterative: code too long/complicated with stack
public class Solution {
public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
if (root == null || p == null) return null;
Stack<TreeNode> stack = new Stack<>();
while (root != null) {
if (p == root) {
break;
} else if (p.val < root.val) {
if (root.left == null) return null;
stack.push(root);
root = root.left;
} else { //p.val > root.val
if (root.right == null) return null;
root = root.right;
}
}
if (root.right != null) { //in-order next node: Hunt down rightNode's left leaf
TreeNode rst = root.right;
while (rst.left != null) {
rst = rst.left;
}
return rst;
} else if (!stack.isEmpty()) {
return stack.pop(); //Inorder pattern rules:
}
return null;
}
}
/*
Analysis the structure.
1. Note1: When directing left, save curr in stack. Curr node will be re-visit with rules of in-order traversal. Write an example, will help refresh memory.
In the future, if node == target && node.right == null, then stack.pop() is the successor.
2. Note2: When p is found, and node.right != null. Be careful where: if node.right just ends there, surely return it, that's it;
However, if rightNode has left child, well, have to trace all the way down to left---end of the leaf
Stack uses O(h) space
*/
// Prev recursive: code too long/complicated with stack.
public class Solution {
Stack<TreeNode> stack = new Stack<>();
public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
if (root == null || p == null) return null;
if (root == p) {
if (root.right != null) { //in-order next node: Hunt down rightNode's left leaf
TreeNode rst = root.right;
while (rst.left != null) {
rst = rst.left;
}
return rst;
} else if (!stack.isEmpty()) {
return stack.pop(); //Inorder pattern rules:
}
return null;
}
if (p.val < root.val && root.left != null) { // search left, with root added at bottom of stack
stack.push(root);
return inorderSuccessor(root.left, p);
} else if (p.val > root.val && root.right != null) { // search right
return inorderSuccessor(root.right, p);
}
return null;
}
}
```