Skip to content

Commit c80cfae

Browse files
committed
fd
1 parent 74e6826 commit c80cfae

File tree

5 files changed

+209
-92
lines changed

5 files changed

+209
-92
lines changed

build.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
buildscript {
44
repositories {
55
jcenter()
6+
maven { url 'https://maven.google.com' }
67
}
78
dependencies {
89
classpath 'com.android.tools.build:gradle:3.0.0'
@@ -15,6 +16,7 @@ buildscript {
1516
allprojects {
1617
repositories {
1718
jcenter()
19+
maven { url 'https://maven.google.com' }
1820
}
1921
}
2022

library/src/main/java/com/leetcode/library/TreeNode.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@ public TreeNode(int x, TreeNode left, TreeNode right) {
2020
this.right = right;
2121
}
2222

23+
// public static TreeNode buildTree(Integer... array) {
24+
// Integer[] s = new Integer[array.length];
25+
// for (int i = 0; i < array.length; i++) {
26+
// s[i] = array[i];
27+
// }
28+
// return buildTree(s);
29+
// }
30+
2331
/**
2432
* 建立完全二叉树
2533
*/

solution/src/main/java/com/inuker/solution/ClosestBinarySearchTreeValueII.java

Lines changed: 116 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -22,50 +22,8 @@ public class ClosestBinarySearchTreeValueII {
2222
// https://discuss.leetcode.com/topic/22940/ac-clean-java-solution-using-two-stacks/2
2323
// https://discuss.leetcode.com/topic/23151/o-logn-java-solution-with-two-stacks-following-hint
2424

25-
// 耗时5ms,时间复杂度O(n)
26-
public List<Integer> closestKValues(TreeNode root, double target, int k) {
27-
List<TreeNode> list = new ArrayList<TreeNode>();
28-
inorderTraversal(root, list);
29-
30-
int index = -1;
31-
double min = Double.MAX_VALUE;
32-
for (int i = 0; i < list.size(); i++) {
33-
double delta = Math.abs(list.get(i).val - target);
34-
if (delta < min) {
35-
min = delta;
36-
index = i;
37-
} else {
38-
break;
39-
}
40-
}
41-
42-
List<Integer> result = new LinkedList<Integer>();
43-
result.add(list.get(index).val);
44-
45-
for (int i = index - 1, j = index + 1; result.size() < k; ) {
46-
double delta1 = i >= 0 ? Math.abs(list.get(i).val - target) : Double.MAX_VALUE;
47-
double delta2 = j < list.size() ? Math.abs(list.get(j).val - target) : Double.MAX_VALUE;
48-
if (delta1 > delta2) {
49-
result.add(list.get(j++).val);
50-
} else {
51-
result.add(list.get(i--).val);
52-
}
53-
}
5425

55-
return result;
56-
}
57-
58-
private void inorderTraversal(TreeNode root, List<TreeNode> list) {
59-
if (root == null) {
60-
return;
61-
}
62-
inorderTraversal(root.left, list);
63-
list.add(root);
64-
inorderTraversal(root.right, list);
65-
}
66-
67-
68-
/** 复杂度O(n + k),双栈挺巧妙
26+
/** 复杂度O(n + k)*/
6927
public List<Integer> closestKValues(TreeNode root, double target, int k) {
7028
Stack<TreeNode> preStack = new Stack<>();
7129
Stack<TreeNode> postStack = new Stack<>();
@@ -107,5 +65,119 @@ private void inorderTraverse(Stack<TreeNode> stack0, TreeNode root, double targe
10765
root = reverse ? node.left : node.right;
10866
}
10967
}
110-
}*/
68+
}
69+
70+
/**
71+
* 形成双栈其实不用O(n),当树是平衡二叉树时,有O(lgn)的写法,如下
72+
* 返回的是对于给定target,返回该target的所有successor和predesessor
73+
*/
74+
public List<TreeNode> getAllSuccessor(TreeNode root, int target) {
75+
Stack<TreeNode> stack = new Stack<>();
76+
buildSuccessorStack(root, stack, target);
77+
List<TreeNode> list = new LinkedList<>();
78+
TreeNode next;
79+
while ((next = getNextSuccessor(stack)) != null) {
80+
if (next.val != target) {
81+
list.add(next);
82+
}
83+
}
84+
return list;
85+
}
86+
87+
private void buildSuccessorStack(TreeNode root, Stack<TreeNode> stack, int target) {
88+
for (TreeNode node = root; node != null; ) {
89+
if (target <= node.val) {
90+
stack.push(node);
91+
node = node.left;
92+
} else {
93+
node = node.right;
94+
}
95+
}
96+
}
97+
98+
/**
99+
* 右child的最左下角
100+
*/
101+
private TreeNode getNextSuccessor(Stack<TreeNode> stack) {
102+
if (stack.isEmpty()) {
103+
return null;
104+
}
105+
TreeNode ret = stack.pop();
106+
for (TreeNode node = ret.right; node != null; node = node.left) {
107+
stack.push(node);
108+
}
109+
return ret;
110+
}
111+
112+
public List<TreeNode> getAllPredesessor(TreeNode root, int target) {
113+
Stack<TreeNode> stack = new Stack<>();
114+
buildPredesessorStack(root, stack, target);
115+
List<TreeNode> list = new LinkedList<>();
116+
TreeNode next;
117+
while ((next = getNextPredesessor(stack)) != null) {
118+
if (next.val != target) {
119+
list.add(next);
120+
}
121+
}
122+
return list;
123+
}
124+
125+
private void buildPredesessorStack(TreeNode root, Stack<TreeNode> stack, int target) {
126+
for (TreeNode node = root; node != null; ) {
127+
if (target >= node.val) {
128+
stack.push(node);
129+
node = node.right;
130+
} else {
131+
node = node.left;
132+
}
133+
}
134+
}
135+
136+
/**
137+
* 左child的最右下角
138+
*/
139+
private TreeNode getNextPredesessor(Stack<TreeNode> stack) {
140+
if (stack.isEmpty()) {
141+
return null;
142+
}
143+
TreeNode ret = stack.pop();
144+
for (TreeNode node = ret.left; node != null; node = node.right) {
145+
stack.push(node);
146+
}
147+
return ret;
148+
}
149+
150+
/**
151+
* 结合上面的代码,可以有如下写法:
152+
*/
153+
public List<Integer> closestKValues2(TreeNode root, double target, int k) {
154+
Stack<TreeNode> preStack = new Stack<>();
155+
Stack<TreeNode> postStack = new Stack<>();
156+
157+
for (TreeNode node = root; node != null; ) {
158+
if (target <= node.val) {
159+
postStack.push(node);
160+
node = node.left;
161+
} else {
162+
preStack.push(node);
163+
node = node.right;
164+
}
165+
}
166+
167+
List<Integer> list = new LinkedList<>();
168+
169+
for (int i = 0; i < k; i++) {
170+
if (preStack.isEmpty()) {
171+
list.add(postStack.pop().val);
172+
} else if (postStack.isEmpty()) {
173+
list.add(preStack.pop().val);
174+
} else if (Math.abs(target - preStack.peek().val) < Math.abs(target - postStack.peek().val)) {
175+
list.add(getNextPredesessor(preStack).val);
176+
} else {
177+
list.add(getNextSuccessor(postStack).val);
178+
}
179+
}
180+
181+
return list;
182+
}
111183
}

solution/src/main/java/com/inuker/solution/InorderSuccessorInBST.java

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import com.leetcode.library.TreeNode;
44

5+
import java.util.LinkedList;
6+
import java.util.List;
57
import java.util.Stack;
68

79
/**
@@ -81,4 +83,78 @@ private TreeNode minValue(TreeNode node) {
8183
}
8284
return node;
8385
}*/
86+
87+
/**
88+
* 这题如果改成给定一个节点,求出其之后的所有successor或predesessor
89+
* 以下可用于 #272. Closest Binary Search Tree Value II
90+
*/
91+
public List<TreeNode> getAllSuccessor(TreeNode root, int target) {
92+
Stack<TreeNode> stack = new Stack<>();
93+
buildSuccessorStack(root, stack, target);
94+
List<TreeNode> list = new LinkedList<>();
95+
TreeNode next;
96+
while ((next = getNextSuccessor(stack)) != null) {
97+
if (next.val != target) {
98+
list.add(next);
99+
}
100+
}
101+
return list;
102+
}
103+
104+
private void buildSuccessorStack(TreeNode root, Stack<TreeNode> stack, int target) {
105+
for (TreeNode node = root; node != null; ) {
106+
if (target <= node.val) {
107+
stack.push(node);
108+
node = node.left;
109+
} else {
110+
node = node.right;
111+
}
112+
}
113+
}
114+
115+
private TreeNode getNextSuccessor(Stack<TreeNode> stack) {
116+
if (stack.isEmpty()) {
117+
return null;
118+
}
119+
TreeNode ret = stack.pop();
120+
for (TreeNode node = ret.right; node != null; node = node.left) {
121+
stack.push(node);
122+
}
123+
return ret;
124+
}
125+
126+
public List<TreeNode> getAllPredesessor(TreeNode root, int target) {
127+
Stack<TreeNode> stack = new Stack<>();
128+
buildPredesessorStack(root, stack, target);
129+
List<TreeNode> list = new LinkedList<>();
130+
TreeNode next;
131+
while ((next = getNextPredesessor(stack)) != null) {
132+
if (next.val != target) {
133+
list.add(next);
134+
}
135+
}
136+
return list;
137+
}
138+
139+
private void buildPredesessorStack(TreeNode root, Stack<TreeNode> stack, int target) {
140+
for (TreeNode node = root; node != null; ) {
141+
if (target >= node.val) {
142+
stack.push(node);
143+
node = node.right;
144+
} else {
145+
node = node.left;
146+
}
147+
}
148+
}
149+
150+
private TreeNode getNextPredesessor(Stack<TreeNode> stack) {
151+
if (stack.isEmpty()) {
152+
return null;
153+
}
154+
TreeNode ret = stack.pop();
155+
for (TreeNode node = ret.left; node != null; node = node.right) {
156+
stack.push(node);
157+
}
158+
return ret;
159+
}
84160
}
Lines changed: 7 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,22 @@
11
package com.inuker.test;
22

33
import com.inuker.solution.BinaryTreeInorderTraversal;
4+
import com.inuker.solution.InorderSuccessorInBST;
45
import com.leetcode.library.TreeNode;
56

6-
import java.util.LinkedList;
77
import java.util.List;
8-
import java.util.Stack;
98

109
public class main {
1110

1211
public static void main(String[] args) {
13-
TreeNode node5 = new TreeNode(5);
14-
TreeNode node4 = new TreeNode(4);
15-
TreeNode node3 = new TreeNode(3, node5, node4);
16-
TreeNode node2 = new TreeNode(2, node3, null);
12+
TreeNode root = TreeNode.buildTree(new Integer[]{
13+
20, 10, 40, 5, 15, 30, 60, 2, 7, 12, 18, 25, 35, 50, 70
14+
});
1715

18-
19-
List<Integer> list = new BinaryTreeInorderTraversal().inorderTraversal2(node2);
20-
for (Integer n : list) {
21-
System.out.print(n + " ");
22-
}
23-
}
24-
25-
public List<Integer> closestKValues(TreeNode root, double target, int k) {
26-
Stack<Integer> smaller = new Stack<>();
27-
Stack<Integer> larger = new Stack<>();
28-
helper(root, smaller, target, true);
29-
helper(root, larger, target, false);
30-
List<Integer> result = new LinkedList<>();
31-
for (int i = 0; i < k; i++) {
32-
if (smaller.isEmpty()) {
33-
result.add(larger.pop());
34-
} else if (larger.isEmpty()) {
35-
result.add(smaller.pop());
36-
} else if (Math.abs(smaller.peek() - target) < Math.abs(larger.peek() - target)) {
37-
result.add(smaller.pop());
38-
} else {
39-
result.add(larger.pop());
40-
}
16+
List<TreeNode> list = new InorderSuccessorInBST().getAllPredesessor(root, 40);
17+
for (TreeNode n : list) {
18+
System.out.print(n.val + " ");
4119
}
42-
return result;
4320
}
4421

45-
private void helper(TreeNode root, Stack<Integer> stack0, double target, boolean smaller) {
46-
Stack<TreeNode> stack = new Stack<>();
47-
while (!stack.isEmpty() || root != null) {
48-
if (root != null) {
49-
stack.push(root);
50-
root = smaller ? root.left : root.right;
51-
} else {
52-
root = stack.pop();
53-
54-
if ((smaller && root.val >= target) || (!smaller && root.val < target)) {
55-
return;
56-
}
57-
58-
stack0.push(root.val);
59-
root = smaller ? root.right : root.left;
60-
}
61-
}
62-
}
6322
}

0 commit comments

Comments
 (0)