forked from DengWangBao/Leetcode-Java
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathInorderSuccessorInBST.java
173 lines (158 loc) · 5.18 KB
/
InorderSuccessorInBST.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
173
import java.util.LinkedList;
import java.util.List;
import java.util.Stack;
/**
* 有两种方法,用栈做普通的中序遍历,这种没有充分利用BST的特点
* 第二种方法比较巧妙,首先遍历到p,然后继续遍历找到p的右子树的最小值
*/
public class InorderSuccessorInBST {
// 耗时10ms
// 时间复杂度O(n)
public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode node = null, prev = null;
while (!stack.isEmpty() || node != null) {
if (node != null) {
stack.push(node);
node = node.left;
} else {
node = stack.pop();
if (prev == p) {
return node;
}
prev = node;
node = node.right;
}
}
return null;
}
// 耗时2ms,简单的递归写法,更容易理解
/**
public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
if (root == null) {
return null;
}
if (p.val < root.val) {
TreeNode node = inorderSuccessor(root.left, p);
return node != null ? node : root;
} else {
return inorderSuccessor(root.right, p);
}
}
public TreeNode predecessor(TreeNode root, TreeNode p) {
if (root == null)
return null;
if (root.val >= p.val) {
return predecessor(root.left, p);
} else {
TreeNode right = predecessor(root.right, p);
return (right != null) ? right : root;
}
}*/
// 给上面的递归换成迭代写法
// 耗时4ms
public TreeNode inorderSuccessor2(TreeNode root, TreeNode p) {
TreeNode res = null;
while (root != null) {
if (p.val < root.val) {
res = root;
root = root.left;
} else {
root = root.right;
}
}
return res;
}
/**
* http://www.geeksforgeeks.org/?p=9999
* 给定Node,求其successor,步骤如下:
* 1, 如果Node.right != null,则在Node.right中找最小的那个节点,即从Node.right开始,最左下角的节点
* 2, 如果Node.right == null,则不断往parent走,直到当前节点是其parent的左节点为止,其parent即为给定Node的successor
*/
/*
private TreeNode inOrderSuccessor(TreeNode root, TreeNode node) {
if (node.right != null) {
return minValue(node.right);
}
TreeNode parent = node.parent;
while (parent != null && node == parent.right) {
node = parent;
parent = parent.parent;
}
return parent;
}
private TreeNode minValue(TreeNode node) {
while (node.left != null) {
node = node.left;
}
return node;
}*/
/**
* 这题如果改成给定一个节点,求出其之后的所有successor或predesessor
* 以下可用于 #272. Closest Binary Search Tree Value II
*/
public List<TreeNode> getAllSuccessor(TreeNode root, int target) {
Stack<TreeNode> stack = new Stack<>();
buildSuccessorStack(root, stack, target);
List<TreeNode> list = new LinkedList<>();
TreeNode next;
while ((next = getNextSuccessor(stack)) != null) {
if (next.val != target) {
list.add(next);
}
}
return list;
}
private void buildSuccessorStack(TreeNode root, Stack<TreeNode> stack, int target) {
for (TreeNode node = root; node != null; ) {
if (target <= node.val) {
stack.push(node);
node = node.left;
} else {
node = node.right;
}
}
}
private TreeNode getNextSuccessor(Stack<TreeNode> stack) {
if (stack.isEmpty()) {
return null;
}
TreeNode ret = stack.pop();
for (TreeNode node = ret.right; node != null; node = node.left) {
stack.push(node);
}
return ret;
}
public List<TreeNode> getAllPredesessor(TreeNode root, int target) {
Stack<TreeNode> stack = new Stack<>();
buildPredesessorStack(root, stack, target);
List<TreeNode> list = new LinkedList<>();
TreeNode next;
while ((next = getNextPredesessor(stack)) != null) {
if (next.val != target) {
list.add(next);
}
}
return list;
}
private void buildPredesessorStack(TreeNode root, Stack<TreeNode> stack, int target) {
for (TreeNode node = root; node != null; ) {
if (target >= node.val) {
stack.push(node);
node = node.right;
} else {
node = node.left;
}
}
}
private TreeNode getNextPredesessor(Stack<TreeNode> stack) {
if (stack.isEmpty()) {
return null;
}
TreeNode ret = stack.pop();
for (TreeNode node = ret.left; node != null; node = node.right) {
stack.push(node);
}
return ret;
}
}