forked from DengWangBao/Leetcode-Java
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathInorderSuccessorInBST.java
More file actions
153 lines (141 loc) · 5.02 KB
/
InorderSuccessorInBST.java
File metadata and controls
153 lines (141 loc) · 5.02 KB
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
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;
}
/**
* p的下一个节点一定是比p大的,所以这里遍历时当p的值小于当前节点,则当前节点
* 可作为备选,同时往左走。如果在遍历过程中遇到仍然比p大的,说明更接近p,则更新备选。
*
* 有两点要注意,
* 1, 首先res初始要为null,一个节点时,或root为null时,或p为最大节点时,res都没机会赋值
* 2, 当root迭代到等于p时,走哪个分支呢,为什么选root = root.right,假如root.right为空,则之前的res即可,否则
* 下一个迭代肯定走到root.val > p.val分支中,更新res。
*/
// 耗时4ms
public TreeNode inorderSuccessor2(TreeNode root, TreeNode p) {
TreeNode res = null;
while (root != null) {
if (root.val > p.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;
}
}