0%

algorithm-tree

简单

二叉树的最大深度

题目描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
给定一个二叉树 root ,返回其最大深度。

二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。



示例 1:



输入:root = [3,9,20,null,null,15,7]
输出:3
示例 2:

输入:root = [1,null,2]
输出:2


提示:

树中节点的数量在 [0, 104] 区间内。
-100 <= Node.val <= 100

题目解答

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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
public class Solution {
public int maxDepth(TreeNode root) {
if (root == null) {
return 0;
}

int l = maxDepth(root.left);
int r = maxDepth(root.right);

int k = l;
if (r > l) {
k = r;
}

return k + 1;
}

static class TreeNode {
int val;
TreeNode left;
TreeNode right;

TreeNode() {
}

TreeNode(int val) {
this.val = val;
}

TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}

public static TreeNode genTree(Integer[] array) {
if (array.length == 0) {
return null;
}

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
TreeNode root = new TreeNode(array[0]);
queue.offer(root);

Integer v = null;
int i = 1;
while (i < array.length) {
TreeNode node = queue.poll();

TreeNode left = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;
TreeNode right = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;

// 数组中不包含空节点的子节点的写法(不标准的完全二叉树含空节点的层次遍历)
node.left = left;
node.right = right;
if (left != null) {
queue.offer(left);
}
if (right != null) {
queue.offer(right);
}

// 数组中包含空节点的子节点的写法(标准的完全二叉树含空节点的层次遍历)
// if (node != null) {
// node.left = left;
// node.right = right;
// }
// queue.offer(left);
// queue.offer(right);
}

return root;
}

public static Integer[] toArray(TreeNode root) {
if (root == null) {
return new Integer[0];
}

java.util.LinkedList<Integer> list = new java.util.LinkedList<>();

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
boolean hasValidNode = false;

int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();

if (node != null) {
list.add(node.val);

queue.offer(node.left);
queue.offer(node.right);

if (!hasValidNode) {
hasValidNode = node.left != null || node.right != null;
}
} else {
list.add(null);
}
}

if (!hasValidNode) {
// while (!queue.isEmpty()) {
// queue.poll();
// }

break;
}
}

while (!list.isEmpty() && list.get(list.size() - 1) == null) {
list.remove(list.size() - 1);
}

return list.toArray(new Integer[0]);
}
}
}

class TestMain {

public static void main(String[] args) {
TestUtils.runTestCases(TestCase.class);
}

public static class TestCase {

public static boolean testCase1() {
Integer[] nums = { 3, 9, 20, null, null, 15, 7 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
int result = new Solution().maxDepth(tree);
int expect = 3;

return TestUtils.check(result, expect);
}

public static boolean testCase2() {
Integer[] nums = { 1, null, 2 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
int result = new Solution().maxDepth(tree);
int expect = 2;

return TestUtils.check(result, expect);
}
}

public static class TestUtils {

public static boolean check(Object result, Object expect) {
result = normalizeObject(result);
expect = normalizeObject(expect);
boolean ok = java.util.Objects.deepEquals(result, expect);
printCheck(toString(result), toString(expect), ok);
return ok;
}

public static boolean check(Object result, String expect) {
boolean ok = java.util.Objects.equals(normalizeString(toString(result)),
normalizeString(toString(expect)));
printCheck(normalizeString(toString(result)), normalizeString(toString(expect)), ok);
return ok;
}

private static Object normalizeObject(Object o) {
if (o instanceof java.util.List) {
java.util.List<?> list = (java.util.List<?>) o;
if (list != null && !list.isEmpty() && list.get(0) instanceof java.util.List) {
o = toArrays(list);
} else {
o = toArray(list);
}
}

return o;
}

private static String toString(Object o) {
if (o instanceof Object[]) {
return java.util.Arrays.deepToString((Object[]) o);
} else if (o instanceof int[]) {
return java.util.Arrays.toString((int[]) o);
} else if (o instanceof double[]) {
return java.util.Arrays.toString((double[]) o);
} else if (o instanceof char[]) {
return java.util.Arrays.toString((char[]) o);
} else {
return java.util.Objects.toString(o);
}
}

private static String normalizeString(String s) {
boolean isArray = (s.startsWith("{") && s.endsWith("}")) || (s.startsWith("[") && s.endsWith("]"));
if (isArray) {
s = s.replace(" ", "")
.replace("'", "")
.replace("\"", "")
.replace("{", "[")
.replace("}", "]");
}

return s;
}

private static void printCheck(String result, String expect, boolean ok) {
// System.out.println();
// System.out.println("--->");

System.out.println("result: " + result);
System.out.println("expect: " + expect);

System.out.println();
if (ok) {
System.out.println("比较结果为: 正确(right)");
} else {
System.out.println("比较结果为: 错误(error)");
}

// System.out.println();
// System.out.println("<---");
}

public static void runTestCases(Class<?> clazz) {
java.lang.reflect.Method[] methods = clazz.getDeclaredMethods();
java.util.Arrays.sort(methods, (o1, o2) -> {
return o1.getName().compareTo(o2.getName());
});
for (java.lang.reflect.Method method : methods) {
if (method.getName().startsWith("test")) {
System.out.println(String.format("--- %s --->", method.getName()));

Object object = null;
try {
object = method.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println(String.format("<--- %s ---", method.getName()));

if (object instanceof Boolean) {
Boolean ok = (Boolean) object;
if (!ok) {
break;
}
} else {
throw new RuntimeException(String.format("测试用例方法%s的返回值需要为布尔类型", method.getName()));
}
}
}
}

public static Object[] toArray(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0];
}

return list.toArray();
}

public static Object[][] toArrays(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0][0];
}

Object[][] arrays = new Object[list.size()][];
for (int i = 0; i < list.size(); i++) {
arrays[i] = toArray(list.get(i));
}

return arrays;
}

@SuppressWarnings("unchecked")
public static <T> T[] genArray(Class<T> clazz, int length) {
return (T[]) java.lang.reflect.Array.newInstance(clazz, length);
}

@SuppressWarnings("unchecked")
public static <T> T[][] genArrays(Class<T> clazz, int rows, int cols) {
T[] array = genArray(clazz, 0);

T[][] arrays = (T[][]) genArray(array.getClass(), rows);
for (int i = 0; i < arrays.length; i++) {
arrays[i] = genArray(clazz, cols);
}

return arrays;
}

public static <T> T[] toArray(java.util.List<T> list, Class<T> clazz) {
if (list == null || list.isEmpty()) {
return genArray(clazz, 0);
}

T[] array = genArray(clazz, list.size());
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}

return array;
}

public static <T> T[][] toArrays(java.util.List<java.util.List<T>> lists, Class<T> clazz) {
if (lists == null || lists.isEmpty()) {
return genArrays(clazz, 0, 0);
}

T[][] arrays = genArrays(clazz, lists.size(), 0);
for (int i = 0; i < lists.size(); i++) {
arrays[i] = toArray(lists.get(i), clazz);
}

return arrays;
}

public static <T> java.util.List<T> toList(T[] array) {
return java.util.Arrays.asList(array);
}

public static <T> java.util.List<java.util.List<T>> toLists(T[][] arrays) {
java.util.List<java.util.List<T>> lists = new java.util.ArrayList<>();
for (T[] array : arrays) {
lists.add(toList(array));
}

return lists;
}
}
}

相同的树

题目描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。

如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。



示例 1:

输入:p = [1,2,3], q = [1,2,3]
输出:true
示例 2:

输入:p = [1,2], q = [1,null,2]
输出:false
示例 3:

输入:p = [1,2,1], q = [1,1,2]
输出:false


提示:

两棵树上的节点数目都在范围 [0, 100] 内
-104 <= Node.val <= 104

题目解答

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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
public class Solution {
public boolean isSameTree(TreeNode p, TreeNode q) {
if (p == null && q == null) {
return true;
} else if (p == null || q == null || p.val != q.val) {
return false;
}

return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
}

static class TreeNode {
int val;
TreeNode left;
TreeNode right;

TreeNode() {
}

TreeNode(int val) {
this.val = val;
}

TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}

public static TreeNode genTree(Integer[] array) {
if (array.length == 0) {
return null;
}

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
TreeNode root = new TreeNode(array[0]);
queue.offer(root);

Integer v = null;
int i = 1;
while (i < array.length) {
TreeNode node = queue.poll();

TreeNode left = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;
TreeNode right = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;

// 数组中不包含空节点的子节点的写法(不标准的完全二叉树含空节点的层次遍历)
node.left = left;
node.right = right;
if (left != null) {
queue.offer(left);
}
if (right != null) {
queue.offer(right);
}

// 数组中包含空节点的子节点的写法(标准的完全二叉树含空节点的层次遍历)
// if (node != null) {
// node.left = left;
// node.right = right;
// }
// queue.offer(left);
// queue.offer(right);
}

return root;
}

public static Integer[] toArray(TreeNode root) {
if (root == null) {
return new Integer[0];
}

java.util.LinkedList<Integer> list = new java.util.LinkedList<>();

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
boolean hasValidNode = false;

int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();

if (node != null) {
list.add(node.val);

queue.offer(node.left);
queue.offer(node.right);

if (!hasValidNode) {
hasValidNode = node.left != null || node.right != null;
}
} else {
list.add(null);
}
}

if (!hasValidNode) {
// while (!queue.isEmpty()) {
// queue.poll();
// }

break;
}
}

while (!list.isEmpty() && list.get(list.size() - 1) == null) {
list.remove(list.size() - 1);
}

return list.toArray(new Integer[0]);
}
}
}

class TestMain {

public static void main(String[] args) {
TestUtils.runTestCases(TestCase.class);
}

public static class TestCase {

public static boolean testCase1() {
Integer[] nums1 = { 1, 2, 3 };
Integer[] nums2 = { 1, 2, 3 };

Solution.TreeNode tree1 = Solution.TreeNode.genTree(nums1);
Solution.TreeNode tree2 = Solution.TreeNode.genTree(nums2);
boolean result = new Solution().isSameTree(tree1, tree2);
boolean expect = true;

return TestUtils.check(result, expect);
}

public static boolean testCase2() {
Integer[] nums1 = { 1, 2 };
Integer[] nums2 = { 1, null, 2 };

Solution.TreeNode tree1 = Solution.TreeNode.genTree(nums1);
Solution.TreeNode tree2 = Solution.TreeNode.genTree(nums2);
boolean result = new Solution().isSameTree(tree1, tree2);
boolean expect = false;

return TestUtils.check(result, expect);
}

public static boolean testCase3() {
Integer[] nums1 = { 1, 2, 1 };
Integer[] nums2 = { 1, 1, 2 };

Solution.TreeNode tree1 = Solution.TreeNode.genTree(nums1);
Solution.TreeNode tree2 = Solution.TreeNode.genTree(nums2);
boolean result = new Solution().isSameTree(tree1, tree2);
boolean expect = false;

return TestUtils.check(result, expect);
}
}

public static class TestUtils {

public static boolean check(Object result, Object expect) {
result = normalizeObject(result);
expect = normalizeObject(expect);
boolean ok = java.util.Objects.deepEquals(result, expect);
printCheck(toString(result), toString(expect), ok);
return ok;
}

public static boolean check(Object result, String expect) {
boolean ok = java.util.Objects.equals(normalizeString(toString(result)),
normalizeString(toString(expect)));
printCheck(normalizeString(toString(result)), normalizeString(toString(expect)), ok);
return ok;
}

private static Object normalizeObject(Object o) {
if (o instanceof java.util.List) {
java.util.List<?> list = (java.util.List<?>) o;
if (list != null && !list.isEmpty() && list.get(0) instanceof java.util.List) {
o = toArrays(list);
} else {
o = toArray(list);
}
}

return o;
}

private static String toString(Object o) {
if (o instanceof Object[]) {
return java.util.Arrays.deepToString((Object[]) o);
} else if (o instanceof int[]) {
return java.util.Arrays.toString((int[]) o);
} else if (o instanceof double[]) {
return java.util.Arrays.toString((double[]) o);
} else if (o instanceof char[]) {
return java.util.Arrays.toString((char[]) o);
} else {
return java.util.Objects.toString(o);
}
}

private static String normalizeString(String s) {
boolean isArray = (s.startsWith("{") && s.endsWith("}")) || (s.startsWith("[") && s.endsWith("]"));
if (isArray) {
s = s.replace(" ", "")
.replace("'", "")
.replace("\"", "")
.replace("{", "[")
.replace("}", "]");
}

return s;
}

private static void printCheck(String result, String expect, boolean ok) {
// System.out.println();
// System.out.println("--->");

System.out.println("result: " + result);
System.out.println("expect: " + expect);

System.out.println();
if (ok) {
System.out.println("比较结果为: 正确(right)");
} else {
System.out.println("比较结果为: 错误(error)");
}

// System.out.println();
// System.out.println("<---");
}

public static void runTestCases(Class<?> clazz) {
java.lang.reflect.Method[] methods = clazz.getDeclaredMethods();
java.util.Arrays.sort(methods, (o1, o2) -> {
return o1.getName().compareTo(o2.getName());
});
for (java.lang.reflect.Method method : methods) {
if (method.getName().startsWith("test")) {
System.out.println(String.format("--- %s --->", method.getName()));

Object object = null;
try {
object = method.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println(String.format("<--- %s ---", method.getName()));

if (object instanceof Boolean) {
Boolean ok = (Boolean) object;
if (!ok) {
break;
}
} else {
throw new RuntimeException(String.format("测试用例方法%s的返回值需要为布尔类型", method.getName()));
}
}
}
}

public static Object[] toArray(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0];
}

return list.toArray();
}

public static Object[][] toArrays(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0][0];
}

Object[][] arrays = new Object[list.size()][];
for (int i = 0; i < list.size(); i++) {
arrays[i] = toArray(list.get(i));
}

return arrays;
}

@SuppressWarnings("unchecked")
public static <T> T[] genArray(Class<T> clazz, int length) {
return (T[]) java.lang.reflect.Array.newInstance(clazz, length);
}

@SuppressWarnings("unchecked")
public static <T> T[][] genArrays(Class<T> clazz, int rows, int cols) {
T[] array = genArray(clazz, 0);

T[][] arrays = (T[][]) genArray(array.getClass(), rows);
for (int i = 0; i < arrays.length; i++) {
arrays[i] = genArray(clazz, cols);
}

return arrays;
}

public static <T> T[] toArray(java.util.List<T> list, Class<T> clazz) {
if (list == null || list.isEmpty()) {
return genArray(clazz, 0);
}

T[] array = genArray(clazz, list.size());
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}

return array;
}

public static <T> T[][] toArrays(java.util.List<java.util.List<T>> lists, Class<T> clazz) {
if (lists == null || lists.isEmpty()) {
return genArrays(clazz, 0, 0);
}

T[][] arrays = genArrays(clazz, lists.size(), 0);
for (int i = 0; i < lists.size(); i++) {
arrays[i] = toArray(lists.get(i), clazz);
}

return arrays;
}

public static <T> java.util.List<T> toList(T[] array) {
return java.util.Arrays.asList(array);
}

public static <T> java.util.List<java.util.List<T>> toLists(T[][] arrays) {
java.util.List<java.util.List<T>> lists = new java.util.ArrayList<>();
for (T[] array : arrays) {
lists.add(toList(array));
}

return lists;
}
}
}

翻转二叉树

题目描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。



示例 1:

输入:root = [4,2,7,1,3,6,9]
输出:[4,7,2,9,6,3,1]
示例 2:

输入:root = [2,1,3]
输出:[2,3,1]
示例 3:

输入:root = []
输出:[]


提示:

树中节点数目范围在 [0, 100] 内
-100 <= Node.val <= 100

题目解答

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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
public class Solution {
public TreeNode invertTree(TreeNode root) {
if (root == null) {
return null;
}

TreeNode left = root.left;
TreeNode right = root.right;

root.left = right;
root.right = left;

invertTree(left);
invertTree(right);

return root;
}

static class TreeNode {
int val;
TreeNode left;
TreeNode right;

TreeNode() {
}

TreeNode(int val) {
this.val = val;
}

TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}

public static TreeNode genTree(Integer[] array) {
if (array.length == 0) {
return null;
}

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
TreeNode root = new TreeNode(array[0]);
queue.offer(root);

Integer v = null;
int i = 1;
while (i < array.length) {
TreeNode node = queue.poll();

TreeNode left = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;
TreeNode right = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;

// 数组中不包含空节点的子节点的写法(不标准的完全二叉树含空节点的层次遍历)
node.left = left;
node.right = right;
if (left != null) {
queue.offer(left);
}
if (right != null) {
queue.offer(right);
}

// 数组中包含空节点的子节点的写法(标准的完全二叉树含空节点的层次遍历)
// if (node != null) {
// node.left = left;
// node.right = right;
// }
// queue.offer(left);
// queue.offer(right);
}

return root;
}

public static Integer[] toArray(TreeNode root) {
if (root == null) {
return new Integer[0];
}

java.util.LinkedList<Integer> list = new java.util.LinkedList<>();

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
boolean hasValidNode = false;

int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();

if (node != null) {
list.add(node.val);

queue.offer(node.left);
queue.offer(node.right);

if (!hasValidNode) {
hasValidNode = node.left != null || node.right != null;
}
} else {
list.add(null);
}
}

if (!hasValidNode) {
// while (!queue.isEmpty()) {
// queue.poll();
// }

break;
}
}

while (!list.isEmpty() && list.get(list.size() - 1) == null) {
list.remove(list.size() - 1);
}

return list.toArray(new Integer[0]);
}
}
}

class TestMain {

public static void main(String[] args) {
TestUtils.runTestCases(TestCase.class);
}

public static class TestCase {

public static boolean testCase1() {
Integer[] nums = { 4, 2, 7, 1, 3, 6, 9 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
Solution.TreeNode node = new Solution().invertTree(tree);
Integer[] result = Solution.TreeNode.toArray(node);
Integer[] expect = { 4, 7, 2, 9, 6, 3, 1 };

return TestUtils.check(result, expect);
}

public static boolean testCase2() {
Integer[] nums = { 2, 1, 3 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
Solution.TreeNode node = new Solution().invertTree(tree);
Integer[] result = Solution.TreeNode.toArray(node);
Integer[] expect = { 2, 3, 1 };

return TestUtils.check(result, expect);
}

public static boolean testCase3() {
Integer[] nums = {};

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
Solution.TreeNode node = new Solution().invertTree(tree);
Integer[] result = Solution.TreeNode.toArray(node);
Integer[] expect = {};

return TestUtils.check(result, expect);
}

public static boolean testCase4() {
Integer[] nums = { 3, 9, 20, null, null, 15, 7 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
Solution.TreeNode node = new Solution().invertTree(tree);
Integer[] result = Solution.TreeNode.toArray(node);
Integer[] expect = { 3, 20, 9, 7, 15 };

return TestUtils.check(result, expect);
}

public static boolean testCase5() {
Integer[] nums = { 1, null, 2 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
Solution.TreeNode node = new Solution().invertTree(tree);
Integer[] result = Solution.TreeNode.toArray(node);
Integer[] expect = { 1, 2 };

return TestUtils.check(result, expect);
}
}

public static class TestUtils {

public static boolean check(Object result, Object expect) {
result = normalizeObject(result);
expect = normalizeObject(expect);
boolean ok = java.util.Objects.deepEquals(result, expect);
printCheck(toString(result), toString(expect), ok);
return ok;
}

public static boolean check(Object result, String expect) {
boolean ok = java.util.Objects.equals(normalizeString(toString(result)),
normalizeString(toString(expect)));
printCheck(normalizeString(toString(result)), normalizeString(toString(expect)), ok);
return ok;
}

private static Object normalizeObject(Object o) {
if (o instanceof java.util.List) {
java.util.List<?> list = (java.util.List<?>) o;
if (list != null && !list.isEmpty() && list.get(0) instanceof java.util.List) {
o = toArrays(list);
} else {
o = toArray(list);
}
}

return o;
}

private static String toString(Object o) {
if (o instanceof Object[]) {
return java.util.Arrays.deepToString((Object[]) o);
} else if (o instanceof int[]) {
return java.util.Arrays.toString((int[]) o);
} else if (o instanceof double[]) {
return java.util.Arrays.toString((double[]) o);
} else if (o instanceof char[]) {
return java.util.Arrays.toString((char[]) o);
} else {
return java.util.Objects.toString(o);
}
}

private static String normalizeString(String s) {
boolean isArray = (s.startsWith("{") && s.endsWith("}")) || (s.startsWith("[") && s.endsWith("]"));
if (isArray) {
s = s.replace(" ", "")
.replace("'", "")
.replace("\"", "")
.replace("{", "[")
.replace("}", "]");
}

return s;
}

private static void printCheck(String result, String expect, boolean ok) {
// System.out.println();
// System.out.println("--->");

System.out.println("result: " + result);
System.out.println("expect: " + expect);

System.out.println();
if (ok) {
System.out.println("比较结果为: 正确(right)");
} else {
System.out.println("比较结果为: 错误(error)");
}

// System.out.println();
// System.out.println("<---");
}

public static void runTestCases(Class<?> clazz) {
java.lang.reflect.Method[] methods = clazz.getDeclaredMethods();
java.util.Arrays.sort(methods, (o1, o2) -> {
return o1.getName().compareTo(o2.getName());
});
for (java.lang.reflect.Method method : methods) {
if (method.getName().startsWith("test")) {
System.out.println(String.format("--- %s --->", method.getName()));

Object object = null;
try {
object = method.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println(String.format("<--- %s ---", method.getName()));

if (object instanceof Boolean) {
Boolean ok = (Boolean) object;
if (!ok) {
break;
}
} else {
throw new RuntimeException(String.format("测试用例方法%s的返回值需要为布尔类型", method.getName()));
}
}
}
}

public static Object[] toArray(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0];
}

return list.toArray();
}

public static Object[][] toArrays(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0][0];
}

Object[][] arrays = new Object[list.size()][];
for (int i = 0; i < list.size(); i++) {
arrays[i] = toArray(list.get(i));
}

return arrays;
}

@SuppressWarnings("unchecked")
public static <T> T[] genArray(Class<T> clazz, int length) {
return (T[]) java.lang.reflect.Array.newInstance(clazz, length);
}

@SuppressWarnings("unchecked")
public static <T> T[][] genArrays(Class<T> clazz, int rows, int cols) {
T[] array = genArray(clazz, 0);

T[][] arrays = (T[][]) genArray(array.getClass(), rows);
for (int i = 0; i < arrays.length; i++) {
arrays[i] = genArray(clazz, cols);
}

return arrays;
}

public static <T> T[] toArray(java.util.List<T> list, Class<T> clazz) {
if (list == null || list.isEmpty()) {
return genArray(clazz, 0);
}

T[] array = genArray(clazz, list.size());
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}

return array;
}

public static <T> T[][] toArrays(java.util.List<java.util.List<T>> lists, Class<T> clazz) {
if (lists == null || lists.isEmpty()) {
return genArrays(clazz, 0, 0);
}

T[][] arrays = genArrays(clazz, lists.size(), 0);
for (int i = 0; i < lists.size(); i++) {
arrays[i] = toArray(lists.get(i), clazz);
}

return arrays;
}

public static <T> java.util.List<T> toList(T[] array) {
return java.util.Arrays.asList(array);
}

public static <T> java.util.List<java.util.List<T>> toLists(T[][] arrays) {
java.util.List<java.util.List<T>> lists = new java.util.ArrayList<>();
for (T[] array : arrays) {
lists.add(toList(array));
}

return lists;
}
}
}

对称二叉树

题目描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
给你一个二叉树的根节点 root , 检查它是否轴对称。



示例 1:

输入:root = [1,2,2,3,4,4,3]
输出:true
示例 2:

输入:root = [1,2,2,null,3,null,3]
输出:false


提示:

树中节点数目在范围 [1, 1000] 内
-100 <= Node.val <= 100


进阶:你可以运用递归和迭代两种方法解决这个问题吗?

题目解答

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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
public class Solution {
public boolean isSymmetric(TreeNode root) {
return isSymmetric(root.left, root.right);
}

private boolean isSymmetric(TreeNode p, TreeNode q) {
if (p == null && q == null) {
return true;
} else if (p == null || q == null || p.val != q.val) {
return false;
}

return isSymmetric(p.left, q.right) && isSymmetric(p.right, q.left);
}

static class TreeNode {
int val;
TreeNode left;
TreeNode right;

TreeNode() {
}

TreeNode(int val) {
this.val = val;
}

TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}

public static TreeNode genTree(Integer[] array) {
if (array.length == 0) {
return null;
}

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
TreeNode root = new TreeNode(array[0]);
queue.offer(root);

Integer v = null;
int i = 1;
while (i < array.length) {
TreeNode node = queue.poll();

TreeNode left = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;
TreeNode right = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;

// 数组中不包含空节点的子节点的写法(不标准的完全二叉树含空节点的层次遍历)
node.left = left;
node.right = right;
if (left != null) {
queue.offer(left);
}
if (right != null) {
queue.offer(right);
}

// 数组中包含空节点的子节点的写法(标准的完全二叉树含空节点的层次遍历)
// if (node != null) {
// node.left = left;
// node.right = right;
// }
// queue.offer(left);
// queue.offer(right);
}

return root;
}

public static Integer[] toArray(TreeNode root) {
if (root == null) {
return new Integer[0];
}

java.util.LinkedList<Integer> list = new java.util.LinkedList<>();

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
boolean hasValidNode = false;

int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();

if (node != null) {
list.add(node.val);

queue.offer(node.left);
queue.offer(node.right);

if (!hasValidNode) {
hasValidNode = node.left != null || node.right != null;
}
} else {
list.add(null);
}
}

if (!hasValidNode) {
// while (!queue.isEmpty()) {
// queue.poll();
// }

break;
}
}

while (!list.isEmpty() && list.get(list.size() - 1) == null) {
list.remove(list.size() - 1);
}

return list.toArray(new Integer[0]);
}
}
}

class TestMain {

public static void main(String[] args) {
TestUtils.runTestCases(TestCase.class);
}

public static class TestCase {

public static boolean testCase1() {
Integer[] nums = { 1, 2, 2, 3, 4, 4, 3 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
boolean result = new Solution().isSymmetric(tree);
boolean expect = true;

return TestUtils.check(result, expect);
}

public static boolean testCase2() {
Integer[] nums = { 1, 2, 2, null, 3, null, 3 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
boolean result = new Solution().isSymmetric(tree);
boolean expect = false;

return TestUtils.check(result, expect);
}
}

public static class TestUtils {

public static boolean check(Object result, Object expect) {
result = normalizeObject(result);
expect = normalizeObject(expect);
boolean ok = java.util.Objects.deepEquals(result, expect);
printCheck(toString(result), toString(expect), ok);
return ok;
}

public static boolean check(Object result, String expect) {
boolean ok = java.util.Objects.equals(normalizeString(toString(result)),
normalizeString(toString(expect)));
printCheck(normalizeString(toString(result)), normalizeString(toString(expect)), ok);
return ok;
}

private static Object normalizeObject(Object o) {
if (o instanceof java.util.List) {
java.util.List<?> list = (java.util.List<?>) o;
if (list != null && !list.isEmpty() && list.get(0) instanceof java.util.List) {
o = toArrays(list);
} else {
o = toArray(list);
}
}

return o;
}

private static String toString(Object o) {
if (o instanceof Object[]) {
return java.util.Arrays.deepToString((Object[]) o);
} else if (o instanceof int[]) {
return java.util.Arrays.toString((int[]) o);
} else if (o instanceof double[]) {
return java.util.Arrays.toString((double[]) o);
} else if (o instanceof char[]) {
return java.util.Arrays.toString((char[]) o);
} else {
return java.util.Objects.toString(o);
}
}

private static String normalizeString(String s) {
boolean isArray = (s.startsWith("{") && s.endsWith("}")) || (s.startsWith("[") && s.endsWith("]"));
if (isArray) {
s = s.replace(" ", "")
.replace("'", "")
.replace("\"", "")
.replace("{", "[")
.replace("}", "]");
}

return s;
}

private static void printCheck(String result, String expect, boolean ok) {
// System.out.println();
// System.out.println("--->");

System.out.println("result: " + result);
System.out.println("expect: " + expect);

System.out.println();
if (ok) {
System.out.println("比较结果为: 正确(right)");
} else {
System.out.println("比较结果为: 错误(error)");
}

// System.out.println();
// System.out.println("<---");
}

public static void runTestCases(Class<?> clazz) {
java.lang.reflect.Method[] methods = clazz.getDeclaredMethods();
java.util.Arrays.sort(methods, (o1, o2) -> {
return o1.getName().compareTo(o2.getName());
});
for (java.lang.reflect.Method method : methods) {
if (method.getName().startsWith("test")) {
System.out.println(String.format("--- %s --->", method.getName()));

Object object = null;
try {
object = method.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println(String.format("<--- %s ---", method.getName()));

if (object instanceof Boolean) {
Boolean ok = (Boolean) object;
if (!ok) {
break;
}
} else {
throw new RuntimeException(String.format("测试用例方法%s的返回值需要为布尔类型", method.getName()));
}
}
}
}

public static Object[] toArray(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0];
}

return list.toArray();
}

public static Object[][] toArrays(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0][0];
}

Object[][] arrays = new Object[list.size()][];
for (int i = 0; i < list.size(); i++) {
arrays[i] = toArray(list.get(i));
}

return arrays;
}

@SuppressWarnings("unchecked")
public static <T> T[] genArray(Class<T> clazz, int length) {
return (T[]) java.lang.reflect.Array.newInstance(clazz, length);
}

@SuppressWarnings("unchecked")
public static <T> T[][] genArrays(Class<T> clazz, int rows, int cols) {
T[] array = genArray(clazz, 0);

T[][] arrays = (T[][]) genArray(array.getClass(), rows);
for (int i = 0; i < arrays.length; i++) {
arrays[i] = genArray(clazz, cols);
}

return arrays;
}

public static <T> T[] toArray(java.util.List<T> list, Class<T> clazz) {
if (list == null || list.isEmpty()) {
return genArray(clazz, 0);
}

T[] array = genArray(clazz, list.size());
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}

return array;
}

public static <T> T[][] toArrays(java.util.List<java.util.List<T>> lists, Class<T> clazz) {
if (lists == null || lists.isEmpty()) {
return genArrays(clazz, 0, 0);
}

T[][] arrays = genArrays(clazz, lists.size(), 0);
for (int i = 0; i < lists.size(); i++) {
arrays[i] = toArray(lists.get(i), clazz);
}

return arrays;
}

public static <T> java.util.List<T> toList(T[] array) {
return java.util.Arrays.asList(array);
}

public static <T> java.util.List<java.util.List<T>> toLists(T[][] arrays) {
java.util.List<java.util.List<T>> lists = new java.util.ArrayList<>();
for (T[] array : arrays) {
lists.add(toList(array));
}

return lists;
}
}
}

进阶解法

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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
import java.util.LinkedList;
import java.util.Queue;

public class Solution {
public boolean isSymmetric(TreeNode root) {
Queue<TreeNode> lQueue = new LinkedList<>();
Queue<TreeNode> rQueue = new LinkedList<>();

lQueue.offer(root.left);
rQueue.offer(root.right);

while (!lQueue.isEmpty() && !rQueue.isEmpty()) {
TreeNode lNode = lQueue.poll();
TreeNode rNode = rQueue.poll();

if (lNode == null && rNode == null) {
// do nothing
} else if (lNode != null && rNode != null) {
if (lNode.val == rNode.val) {
// 左队列里的结点从左到右处理
lQueue.offer(lNode.left);
lQueue.offer(lNode.right);

// 右队列里的结点从右到左处理
rQueue.offer(rNode.right);
rQueue.offer(rNode.left);
} else {
return false;
}
} else {
return false;
}
}

return lQueue.isEmpty() && rQueue.isEmpty();
}

static class TreeNode {
int val;
TreeNode left;
TreeNode right;

TreeNode() {
}

TreeNode(int val) {
this.val = val;
}

TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}

public static TreeNode genTree(Integer[] array) {
if (array.length == 0) {
return null;
}

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
TreeNode root = new TreeNode(array[0]);
queue.offer(root);

Integer v = null;
int i = 1;
while (i < array.length) {
TreeNode node = queue.poll();

TreeNode left = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;
TreeNode right = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;

// 数组中不包含空节点的子节点的写法(不标准的完全二叉树含空节点的层次遍历)
node.left = left;
node.right = right;
if (left != null) {
queue.offer(left);
}
if (right != null) {
queue.offer(right);
}

// 数组中包含空节点的子节点的写法(标准的完全二叉树含空节点的层次遍历)
// if (node != null) {
// node.left = left;
// node.right = right;
// }
// queue.offer(left);
// queue.offer(right);
}

return root;
}

public static Integer[] toArray(TreeNode root) {
if (root == null) {
return new Integer[0];
}

java.util.LinkedList<Integer> list = new java.util.LinkedList<>();

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
boolean hasValidNode = false;

int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();

if (node != null) {
list.add(node.val);

queue.offer(node.left);
queue.offer(node.right);

if (!hasValidNode) {
hasValidNode = node.left != null || node.right != null;
}
} else {
list.add(null);
}
}

if (!hasValidNode) {
// while (!queue.isEmpty()) {
// queue.poll();
// }

break;
}
}

while (!list.isEmpty() && list.get(list.size() - 1) == null) {
list.remove(list.size() - 1);
}

return list.toArray(new Integer[0]);
}
}
}

class TestMain {

public static void main(String[] args) {
TestUtils.runTestCases(TestCase.class);
}

public static class TestCase {

public static boolean testCase1() {
Integer[] nums = { 1, 2, 2, 3, 4, 4, 3 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
boolean result = new Solution().isSymmetric(tree);
boolean expect = true;

return TestUtils.check(result, expect);
}

public static boolean testCase2() {
Integer[] nums = { 1, 2, 2, null, 3, null, 3 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
boolean result = new Solution().isSymmetric(tree);
boolean expect = false;

return TestUtils.check(result, expect);
}
}

public static class TestUtils {

public static boolean check(Object result, Object expect) {
result = normalizeObject(result);
expect = normalizeObject(expect);
boolean ok = java.util.Objects.deepEquals(result, expect);
printCheck(toString(result), toString(expect), ok);
return ok;
}

public static boolean check(Object result, String expect) {
boolean ok = java.util.Objects.equals(normalizeString(toString(result)),
normalizeString(toString(expect)));
printCheck(normalizeString(toString(result)), normalizeString(toString(expect)), ok);
return ok;
}

private static Object normalizeObject(Object o) {
if (o instanceof java.util.List) {
java.util.List<?> list = (java.util.List<?>) o;
if (list != null && !list.isEmpty() && list.get(0) instanceof java.util.List) {
o = toArrays(list);
} else {
o = toArray(list);
}
}

return o;
}

private static String toString(Object o) {
if (o instanceof Object[]) {
return java.util.Arrays.deepToString((Object[]) o);
} else if (o instanceof int[]) {
return java.util.Arrays.toString((int[]) o);
} else if (o instanceof double[]) {
return java.util.Arrays.toString((double[]) o);
} else if (o instanceof char[]) {
return java.util.Arrays.toString((char[]) o);
} else {
return java.util.Objects.toString(o);
}
}

private static String normalizeString(String s) {
boolean isArray = (s.startsWith("{") && s.endsWith("}")) || (s.startsWith("[") && s.endsWith("]"));
if (isArray) {
s = s.replace(" ", "")
.replace("'", "")
.replace("\"", "")
.replace("{", "[")
.replace("}", "]");
}

return s;
}

private static void printCheck(String result, String expect, boolean ok) {
// System.out.println();
// System.out.println("--->");

System.out.println("result: " + result);
System.out.println("expect: " + expect);

System.out.println();
if (ok) {
System.out.println("比较结果为: 正确(right)");
} else {
System.out.println("比较结果为: 错误(error)");
}

// System.out.println();
// System.out.println("<---");
}

public static void runTestCases(Class<?> clazz) {
java.lang.reflect.Method[] methods = clazz.getDeclaredMethods();
java.util.Arrays.sort(methods, (o1, o2) -> {
return o1.getName().compareTo(o2.getName());
});
for (java.lang.reflect.Method method : methods) {
if (method.getName().startsWith("test")) {
System.out.println(String.format("--- %s --->", method.getName()));

Object object = null;
try {
object = method.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println(String.format("<--- %s ---", method.getName()));

if (object instanceof Boolean) {
Boolean ok = (Boolean) object;
if (!ok) {
break;
}
} else {
throw new RuntimeException(String.format("测试用例方法%s的返回值需要为布尔类型", method.getName()));
}
}
}
}

public static Object[] toArray(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0];
}

return list.toArray();
}

public static Object[][] toArrays(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0][0];
}

Object[][] arrays = new Object[list.size()][];
for (int i = 0; i < list.size(); i++) {
arrays[i] = toArray(list.get(i));
}

return arrays;
}

@SuppressWarnings("unchecked")
public static <T> T[] genArray(Class<T> clazz, int length) {
return (T[]) java.lang.reflect.Array.newInstance(clazz, length);
}

@SuppressWarnings("unchecked")
public static <T> T[][] genArrays(Class<T> clazz, int rows, int cols) {
T[] array = genArray(clazz, 0);

T[][] arrays = (T[][]) genArray(array.getClass(), rows);
for (int i = 0; i < arrays.length; i++) {
arrays[i] = genArray(clazz, cols);
}

return arrays;
}

public static <T> T[] toArray(java.util.List<T> list, Class<T> clazz) {
if (list == null || list.isEmpty()) {
return genArray(clazz, 0);
}

T[] array = genArray(clazz, list.size());
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}

return array;
}

public static <T> T[][] toArrays(java.util.List<java.util.List<T>> lists, Class<T> clazz) {
if (lists == null || lists.isEmpty()) {
return genArrays(clazz, 0, 0);
}

T[][] arrays = genArrays(clazz, lists.size(), 0);
for (int i = 0; i < lists.size(); i++) {
arrays[i] = toArray(lists.get(i), clazz);
}

return arrays;
}

public static <T> java.util.List<T> toList(T[] array) {
return java.util.Arrays.asList(array);
}

public static <T> java.util.List<java.util.List<T>> toLists(T[][] arrays) {
java.util.List<java.util.List<T>> lists = new java.util.ArrayList<>();
for (T[] array : arrays) {
lists.add(toList(array));
}

return lists;
}
}
}

从前序与中序遍历序列构造二叉树

题目描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。



示例 1:

输入: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
输出: [3,9,20,null,null,15,7]
示例 2:

输入: preorder = [-1], inorder = [-1]
输出: [-1]


提示:

1 <= preorder.length <= 3000
inorder.length == preorder.length
-3000 <= preorder[i], inorder[i] <= 3000
preorder 和 inorder 均 无重复 元素
inorder 均出现在 preorder
preorder 保证 为二叉树的前序遍历序列
inorder 保证 为二叉树的中序遍历序列

题目解答

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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
import java.util.HashMap;
import java.util.Map;

public class Solution {
private Map<Integer, Integer> map = new HashMap<>();

public TreeNode buildTree(int[] preorder, int[] inorder) {
// 前序遍历[根结点,左子树的前序遍历,右子树的前序遍历]
// 中序遍历[左子树的的中序遍历,根结点,右子树的的中序遍历]
// 先找到根结点(前序遍历的第一个)在中序遍历中的位置
// 然后利用根结点位置在中序遍历中进行分割求出左子树的中序遍历和右子树的中序遍历
// 然后利用左子树和右子树的长度在前序遍历求出左子树的前序遍历和右子树的前序遍历
// 然后再继续生成左子树和右子树

for (int i = 0; i < inorder.length; i++) {
map.put(inorder[i], i);
}

return buildTree(preorder, inorder, 0, preorder.length - 1, 0, inorder.length - 1);
}

private TreeNode buildTree(int[] preorder, int[] inorder, int preX, int preY, int inX, int inY) {
if (preX > preY) {
return null;
}

int rootVal = preorder[preX];
TreeNode rootNode = new TreeNode(rootVal);

int rootIndex = map.get(rootVal);

int leftInX = inX;
int leftInY = rootIndex - 1;
int leftCount = leftInY - leftInX + 1;
int rightInX = rootIndex + 1;
int rightInY = inY;
int rightCount = rightInY - rightInX + 1;

if (leftCount > 0) {
int leftPreX = preX + 1;
int leftPreY = leftPreX + leftCount - 1;

rootNode.left = buildTree(preorder, inorder, leftPreX, leftPreY, leftInX, leftInY);
}

if (rightCount > 0) {
int rightPreY = preY;
int rightPreX = rightPreY - rightCount + 1;

rootNode.right = buildTree(preorder, inorder, rightPreX, rightPreY, rightInX, rightInY);
}

return rootNode;
}

static class TreeNode {
int val;
TreeNode left;
TreeNode right;

TreeNode() {
}

TreeNode(int val) {
this.val = val;
}

TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}

public static TreeNode genTree(Integer[] array) {
if (array.length == 0) {
return null;
}

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
TreeNode root = new TreeNode(array[0]);
queue.offer(root);

Integer v = null;
int i = 1;
while (i < array.length) {
TreeNode node = queue.poll();

TreeNode left = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;
TreeNode right = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;

// 数组中不包含空节点的子节点的写法(不标准的完全二叉树含空节点的层次遍历)
node.left = left;
node.right = right;
if (left != null) {
queue.offer(left);
}
if (right != null) {
queue.offer(right);
}

// 数组中包含空节点的子节点的写法(标准的完全二叉树含空节点的层次遍历)
// if (node != null) {
// node.left = left;
// node.right = right;
// }
// queue.offer(left);
// queue.offer(right);
}

return root;
}

public static Integer[] toArray(TreeNode root) {
if (root == null) {
return new Integer[0];
}

java.util.LinkedList<Integer> list = new java.util.LinkedList<>();

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
boolean hasValidNode = false;

int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();

if (node != null) {
list.add(node.val);

queue.offer(node.left);
queue.offer(node.right);

if (!hasValidNode) {
hasValidNode = node.left != null || node.right != null;
}
} else {
list.add(null);
}
}

if (!hasValidNode) {
// while (!queue.isEmpty()) {
// queue.poll();
// }

break;
}
}

while (!list.isEmpty() && list.get(list.size() - 1) == null) {
list.remove(list.size() - 1);
}

return list.toArray(new Integer[0]);
}
}
}

class TestMain {

public static void main(String[] args) {
TestUtils.runTestCases(TestCase.class);
}

public static class TestCase {

public static boolean testCase1() {
int[] preorder = { 3, 9, 20, 15, 7 };
int[] inorder = { 9, 3, 15, 20, 7 };

Solution.TreeNode node = new Solution().buildTree(preorder, inorder);
Integer[] result = Solution.TreeNode.toArray(node);
Integer[] expect = { 3, 9, 20, null, null, 15, 7 };

return TestUtils.check(result, expect);
}

public static boolean testCase2() {
int[] preorder = { -1 };
int[] inorder = { -1 };

Solution.TreeNode node = new Solution().buildTree(preorder, inorder);
Integer[] result = Solution.TreeNode.toArray(node);
Integer[] expect = { -1 };

return TestUtils.check(result, expect);
}
}

public static class TestUtils {

public static boolean check(Object result, Object expect) {
result = normalizeObject(result);
expect = normalizeObject(expect);
boolean ok = java.util.Objects.deepEquals(result, expect);
printCheck(toString(result), toString(expect), ok);
return ok;
}

public static boolean check(Object result, String expect) {
boolean ok = java.util.Objects.equals(normalizeString(toString(result)),
normalizeString(toString(expect)));
printCheck(normalizeString(toString(result)), normalizeString(toString(expect)), ok);
return ok;
}

private static Object normalizeObject(Object o) {
if (o instanceof java.util.List) {
java.util.List<?> list = (java.util.List<?>) o;
if (list != null && !list.isEmpty() && list.get(0) instanceof java.util.List) {
o = toArrays(list);
} else {
o = toArray(list);
}
}

return o;
}

private static String toString(Object o) {
if (o instanceof Object[]) {
return java.util.Arrays.deepToString((Object[]) o);
} else if (o instanceof int[]) {
return java.util.Arrays.toString((int[]) o);
} else if (o instanceof double[]) {
return java.util.Arrays.toString((double[]) o);
} else if (o instanceof char[]) {
return java.util.Arrays.toString((char[]) o);
} else {
return java.util.Objects.toString(o);
}
}

private static String normalizeString(String s) {
boolean isArray = (s.startsWith("{") && s.endsWith("}")) || (s.startsWith("[") && s.endsWith("]"));
if (isArray) {
s = s.replace(" ", "")
.replace("'", "")
.replace("\"", "")
.replace("{", "[")
.replace("}", "]");
}

return s;
}

private static void printCheck(String result, String expect, boolean ok) {
// System.out.println();
// System.out.println("--->");

System.out.println("result: " + result);
System.out.println("expect: " + expect);

System.out.println();
if (ok) {
System.out.println("比较结果为: 正确(right)");
} else {
System.out.println("比较结果为: 错误(error)");
}

// System.out.println();
// System.out.println("<---");
}

public static void runTestCases(Class<?> clazz) {
java.lang.reflect.Method[] methods = clazz.getDeclaredMethods();
java.util.Arrays.sort(methods, (o1, o2) -> {
return o1.getName().compareTo(o2.getName());
});
for (java.lang.reflect.Method method : methods) {
if (method.getName().startsWith("test")) {
System.out.println(String.format("--- %s --->", method.getName()));

Object object = null;
try {
object = method.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println(String.format("<--- %s ---", method.getName()));

if (object instanceof Boolean) {
Boolean ok = (Boolean) object;
if (!ok) {
break;
}
} else {
throw new RuntimeException(String.format("测试用例方法%s的返回值需要为布尔类型", method.getName()));
}
}
}
}

public static Object[] toArray(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0];
}

return list.toArray();
}

public static Object[][] toArrays(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0][0];
}

Object[][] arrays = new Object[list.size()][];
for (int i = 0; i < list.size(); i++) {
arrays[i] = toArray(list.get(i));
}

return arrays;
}

@SuppressWarnings("unchecked")
public static <T> T[] genArray(Class<T> clazz, int length) {
return (T[]) java.lang.reflect.Array.newInstance(clazz, length);
}

@SuppressWarnings("unchecked")
public static <T> T[][] genArrays(Class<T> clazz, int rows, int cols) {
T[] array = genArray(clazz, 0);

T[][] arrays = (T[][]) genArray(array.getClass(), rows);
for (int i = 0; i < arrays.length; i++) {
arrays[i] = genArray(clazz, cols);
}

return arrays;
}

public static <T> T[] toArray(java.util.List<T> list, Class<T> clazz) {
if (list == null || list.isEmpty()) {
return genArray(clazz, 0);
}

T[] array = genArray(clazz, list.size());
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}

return array;
}

public static <T> T[][] toArrays(java.util.List<java.util.List<T>> lists, Class<T> clazz) {
if (lists == null || lists.isEmpty()) {
return genArrays(clazz, 0, 0);
}

T[][] arrays = genArrays(clazz, lists.size(), 0);
for (int i = 0; i < lists.size(); i++) {
arrays[i] = toArray(lists.get(i), clazz);
}

return arrays;
}

public static <T> java.util.List<T> toList(T[] array) {
return java.util.Arrays.asList(array);
}

public static <T> java.util.List<java.util.List<T>> toLists(T[][] arrays) {
java.util.List<java.util.List<T>> lists = new java.util.ArrayList<>();
for (T[] array : arrays) {
lists.add(toList(array));
}

return lists;
}
}
}

其他解法

解法1

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
class Solution {
private Map<Integer, Integer> indexMap;

public TreeNode myBuildTree(int[] preorder, int[] inorder, int preorder_left, int preorder_right, int inorder_left, int inorder_right) {
if (preorder_left > preorder_right) {
return null;
}

// 前序遍历中的第一个节点就是根节点
int preorder_root = preorder_left;
// 在中序遍历中定位根节点
int inorder_root = indexMap.get(preorder[preorder_root]);

// 先把根节点建立出来
TreeNode root = new TreeNode(preorder[preorder_root]);
// 得到左子树中的节点数目
int size_left_subtree = inorder_root - inorder_left;
// 递归地构造左子树,并连接到根节点
// 先序遍历中「从 左边界+1 开始的 size_left_subtree」个元素就对应了中序遍历中「从 左边界 开始到 根节点定位-1」的元素
root.left = myBuildTree(preorder, inorder, preorder_left + 1, preorder_left + size_left_subtree, inorder_left, inorder_root - 1);
// 递归地构造右子树,并连接到根节点
// 先序遍历中「从 左边界+1+左子树节点数目 开始到 右边界」的元素就对应了中序遍历中「从 根节点定位+1 到 右边界」的元素
root.right = myBuildTree(preorder, inorder, preorder_left + size_left_subtree + 1, preorder_right, inorder_root + 1, inorder_right);
return root;
}

public TreeNode buildTree(int[] preorder, int[] inorder) {
int n = preorder.length;
// 构造哈希映射,帮助我们快速定位根节点
indexMap = new HashMap<Integer, Integer>();
for (int i = 0; i < n; i++) {
indexMap.put(inorder[i], i);
}
return myBuildTree(preorder, inorder, 0, n - 1, 0, n - 1);
}
}

解法2

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
class Solution {
public TreeNode buildTree(int[] preorder, int[] inorder) {
if (preorder == null || preorder.length == 0) {
return null;
}
TreeNode root = new TreeNode(preorder[0]);
Deque<TreeNode> stack = new LinkedList<TreeNode>();
stack.push(root);
int inorderIndex = 0;
for (int i = 1; i < preorder.length; i++) {
int preorderVal = preorder[i];
TreeNode node = stack.peek();
if (node.val != inorder[inorderIndex]) {
node.left = new TreeNode(preorderVal);
stack.push(node.left);
} else {
while (!stack.isEmpty() && stack.peek().val == inorder[inorderIndex]) {
node = stack.pop();
inorderIndex++;
}
node.right = new TreeNode(preorderVal);
stack.push(node.right);
}
}
return root;
}
}

从中序与后序遍历序列构造二叉树

题目描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。



示例 1:

输入:inorder = [9,3,15,20,7], postorder = [9,15,7,20,3]
输出:[3,9,20,null,null,15,7]
示例 2:

输入:inorder = [-1], postorder = [-1]
输出:[-1]


提示:

1 <= inorder.length <= 3000
postorder.length == inorder.length
-3000 <= inorder[i], postorder[i] <= 3000
inorder 和 postorder 都由 不同 的值组成
postorder 中每一个值都在 inorder 中
inorder 保证是树的中序遍历
postorder 保证是树的后序遍历

题目解答

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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
import java.util.HashMap;
import java.util.Map;

public class Solution {
private Map<Integer, Integer> map = new HashMap<>();

public TreeNode buildTree(int[] inorder, int[] postorder) {
// 后序遍历[左子树的前序遍历,右子树的前序遍历,根结点]
// 中序遍历[左子树的的中序遍历,根结点,右子树的的中序遍历]
// 先找到根结点(前序遍历的第一个)在中序遍历中的位置
// 然后利用根结点位置在中序遍历中进行分割求出左子树的中序遍历和右子树的中序遍历
// 然后利用左子树和右子树的长度在前序遍历求出左子树的前序遍历和右子树的前序遍历
// 然后再继续生成左子树和右子树

for (int i = 0; i < inorder.length; i++) {
map.put(inorder[i], i);
}

return buildTree(inorder, postorder, 0, inorder.length - 1, 0, postorder.length - 1);
}

private TreeNode buildTree(int[] inorder, int[] postorder, int inX, int inY, int postX, int postY) {
if (postX > postY) {
return null;
}

int rootVal = postorder[postY];
TreeNode rootNode = new TreeNode(rootVal);

int rootIndex = map.get(rootVal);

int leftInX = inX;
int leftInY = rootIndex - 1;
int leftCount = leftInY - leftInX + 1;
int rightInX = rootIndex + 1;
int rightInY = inY;
int rightCount = rightInY - rightInX + 1;

if (leftCount > 0) {
int leftPostX = postX;
int leftPostY = leftPostX + leftCount - 1;

rootNode.left = buildTree(inorder, postorder, leftInX, leftInY, leftPostX, leftPostY);
}

if (rightCount > 0) {
int rightPostY = postY - 1;
int rightPostX = rightPostY - rightCount + 1;

rootNode.right = buildTree(inorder, postorder, rightInX, rightInY, rightPostX, rightPostY);
}

return rootNode;
}

static class TreeNode {
int val;
TreeNode left;
TreeNode right;

TreeNode() {
}

TreeNode(int val) {
this.val = val;
}

TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}

public static TreeNode genTree(Integer[] array) {
if (array.length == 0) {
return null;
}

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
TreeNode root = new TreeNode(array[0]);
queue.offer(root);

Integer v = null;
int i = 1;
while (i < array.length) {
TreeNode node = queue.poll();

TreeNode left = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;
TreeNode right = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;

// 数组中不包含空节点的子节点的写法(不标准的完全二叉树含空节点的层次遍历)
node.left = left;
node.right = right;
if (left != null) {
queue.offer(left);
}
if (right != null) {
queue.offer(right);
}

// 数组中包含空节点的子节点的写法(标准的完全二叉树含空节点的层次遍历)
// if (node != null) {
// node.left = left;
// node.right = right;
// }
// queue.offer(left);
// queue.offer(right);
}

return root;
}

public static Integer[] toArray(TreeNode root) {
if (root == null) {
return new Integer[0];
}

java.util.LinkedList<Integer> list = new java.util.LinkedList<>();

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
boolean hasValidNode = false;

int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();

if (node != null) {
list.add(node.val);

queue.offer(node.left);
queue.offer(node.right);

if (!hasValidNode) {
hasValidNode = node.left != null || node.right != null;
}
} else {
list.add(null);
}
}

if (!hasValidNode) {
// while (!queue.isEmpty()) {
// queue.poll();
// }

break;
}
}

while (!list.isEmpty() && list.get(list.size() - 1) == null) {
list.remove(list.size() - 1);
}

return list.toArray(new Integer[0]);
}
}
}

class TestMain {

public static void main(String[] args) {
TestUtils.runTestCases(TestCase.class);
}

public static class TestCase {

public static boolean testCase1() {
int[] inorder = { 9, 3, 15, 20, 7 };
int[] postorder = { 9, 15, 7, 20, 3 };

Solution.TreeNode node = new Solution().buildTree(inorder, postorder);
Integer[] result = Solution.TreeNode.toArray(node);
Integer[] expect = { 3, 9, 20, null, null, 15, 7 };

return TestUtils.check(result, expect);
}

public static boolean testCase2() {
int[] inorder = { -1 };
int[] postorder = { -1 };

Solution.TreeNode node = new Solution().buildTree(inorder, postorder);
Integer[] result = Solution.TreeNode.toArray(node);
Integer[] expect = { -1 };

return TestUtils.check(result, expect);
}
}

public static class TestUtils {

public static boolean check(Object result, Object expect) {
result = normalizeObject(result);
expect = normalizeObject(expect);
boolean ok = java.util.Objects.deepEquals(result, expect);
printCheck(toString(result), toString(expect), ok);
return ok;
}

public static boolean check(Object result, String expect) {
boolean ok = java.util.Objects.equals(normalizeString(toString(result)),
normalizeString(toString(expect)));
printCheck(normalizeString(toString(result)), normalizeString(toString(expect)), ok);
return ok;
}

private static Object normalizeObject(Object o) {
if (o instanceof java.util.List) {
java.util.List<?> list = (java.util.List<?>) o;
if (list != null && !list.isEmpty() && list.get(0) instanceof java.util.List) {
o = toArrays(list);
} else {
o = toArray(list);
}
}

return o;
}

private static String toString(Object o) {
if (o instanceof Object[]) {
return java.util.Arrays.deepToString((Object[]) o);
} else if (o instanceof int[]) {
return java.util.Arrays.toString((int[]) o);
} else if (o instanceof double[]) {
return java.util.Arrays.toString((double[]) o);
} else if (o instanceof char[]) {
return java.util.Arrays.toString((char[]) o);
} else {
return java.util.Objects.toString(o);
}
}

private static String normalizeString(String s) {
boolean isArray = (s.startsWith("{") && s.endsWith("}")) || (s.startsWith("[") && s.endsWith("]"));
if (isArray) {
s = s.replace(" ", "")
.replace("'", "")
.replace("\"", "")
.replace("{", "[")
.replace("}", "]");
}

return s;
}

private static void printCheck(String result, String expect, boolean ok) {
// System.out.println();
// System.out.println("--->");

System.out.println("result: " + result);
System.out.println("expect: " + expect);

System.out.println();
if (ok) {
System.out.println("比较结果为: 正确(right)");
} else {
System.out.println("比较结果为: 错误(error)");
}

// System.out.println();
// System.out.println("<---");
}

public static void runTestCases(Class<?> clazz) {
java.lang.reflect.Method[] methods = clazz.getDeclaredMethods();
java.util.Arrays.sort(methods, (o1, o2) -> {
return o1.getName().compareTo(o2.getName());
});
for (java.lang.reflect.Method method : methods) {
if (method.getName().startsWith("test")) {
System.out.println(String.format("--- %s --->", method.getName()));

Object object = null;
try {
object = method.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println(String.format("<--- %s ---", method.getName()));

if (object instanceof Boolean) {
Boolean ok = (Boolean) object;
if (!ok) {
break;
}
} else {
throw new RuntimeException(String.format("测试用例方法%s的返回值需要为布尔类型", method.getName()));
}
}
}
}

public static Object[] toArray(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0];
}

return list.toArray();
}

public static Object[][] toArrays(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0][0];
}

Object[][] arrays = new Object[list.size()][];
for (int i = 0; i < list.size(); i++) {
arrays[i] = toArray(list.get(i));
}

return arrays;
}

@SuppressWarnings("unchecked")
public static <T> T[] genArray(Class<T> clazz, int length) {
return (T[]) java.lang.reflect.Array.newInstance(clazz, length);
}

@SuppressWarnings("unchecked")
public static <T> T[][] genArrays(Class<T> clazz, int rows, int cols) {
T[] array = genArray(clazz, 0);

T[][] arrays = (T[][]) genArray(array.getClass(), rows);
for (int i = 0; i < arrays.length; i++) {
arrays[i] = genArray(clazz, cols);
}

return arrays;
}

public static <T> T[] toArray(java.util.List<T> list, Class<T> clazz) {
if (list == null || list.isEmpty()) {
return genArray(clazz, 0);
}

T[] array = genArray(clazz, list.size());
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}

return array;
}

public static <T> T[][] toArrays(java.util.List<java.util.List<T>> lists, Class<T> clazz) {
if (lists == null || lists.isEmpty()) {
return genArrays(clazz, 0, 0);
}

T[][] arrays = genArrays(clazz, lists.size(), 0);
for (int i = 0; i < lists.size(); i++) {
arrays[i] = toArray(lists.get(i), clazz);
}

return arrays;
}

public static <T> java.util.List<T> toList(T[] array) {
return java.util.Arrays.asList(array);
}

public static <T> java.util.List<java.util.List<T>> toLists(T[][] arrays) {
java.util.List<java.util.List<T>> lists = new java.util.ArrayList<>();
for (T[] array : arrays) {
lists.add(toList(array));
}

return lists;
}
}
}

其他解法

解法1

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
class Solution {
int post_idx;
int[] postorder;
int[] inorder;
Map<Integer, Integer> idx_map = new HashMap<Integer, Integer>();

public TreeNode helper(int in_left, int in_right) {
// 如果这里没有节点构造二叉树了,就结束
if (in_left > in_right) {
return null;
}

// 选择 post_idx 位置的元素作为当前子树根节点
int root_val = postorder[post_idx];
TreeNode root = new TreeNode(root_val);

// 根据 root 所在位置分成左右两棵子树
int index = idx_map.get(root_val);

// 下标减一
post_idx--;
// 构造右子树
root.right = helper(index + 1, in_right);
// 构造左子树
root.left = helper(in_left, index - 1);
return root;
}

public TreeNode buildTree(int[] inorder, int[] postorder) {
this.postorder = postorder;
this.inorder = inorder;
// 从后序遍历的最后一个元素开始
post_idx = postorder.length - 1;

// 建立(元素,下标)键值对的哈希表
int idx = 0;
for (Integer val : inorder) {
idx_map.put(val, idx++);
}

return helper(0, inorder.length - 1);
}
}

填充每个节点的下一个右侧节点指针II

题目描述

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
struct Node {
int val;
Node *left;
Node *right;
Node *next;
}
填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL 。

初始状态下,所有 next 指针都被设置为 NULL 。



示例 1:

输入:root = [1,2,3,4,5,null,7]
输出:[1,#,2,3,#,4,5,7,#]
解释:给定二叉树如图 A 所示,你的函数应该填充它的每个 next 指针,以指向其下一个右侧节点,如图 B 所示。序列化输出按层序遍历顺序(由 next 指针连接),'#' 表示每层的末尾。
示例 2:

输入:root = []
输出:[]


提示:

树中的节点数在范围 [0, 6000] 内
-100 <= Node.val <= 100
进阶:

你只能使用常量级额外空间。
使用递归解题也符合要求,本题中递归程序的隐式栈空间不计入额外空间复杂度。

题目解答

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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
import java.util.LinkedList;
import java.util.Queue;

public class Solution {
public Node connect(Node root) {
if (root == null) {
return null;
}

Queue<Node> queue = new LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
Node preNode = null;

int size = queue.size();
for (int i = 0; i < size; i++) {
Node node = queue.poll();

if (node.left != null) {
queue.offer(node.left);
}

if (node.right != null) {
queue.offer(node.right);
}

if (preNode != null) {
preNode.next = node;
}

preNode = node;
}
}

return root;
}

static class Node {
public int val;
public Node left;
public Node right;
public Node next;

public Node() {
}

public Node(int _val) {
val = _val;
}

public Node(int _val, Node _left, Node _right, Node _next) {
val = _val;
left = _left;
right = _right;
next = _next;
}

public static Node genTree(Integer[] nums) {
if (nums.length == 0) {
return null;
}

java.util.Queue<Node> queue = new java.util.LinkedList<>();
Node root = new Node(nums[0]);
queue.offer(root);

int i = 1;
while (i < nums.length) {
Node node = queue.poll();

Integer leftVal = i < nums.length ? nums[i++] : null;
if (leftVal != null) {
Node leftNode = new Node(leftVal);
node.left = leftNode;

queue.offer(leftNode);
}

Integer rightVal = i < nums.length ? nums[i++] : null;
if (rightVal != null) {
Node rightNode = new Node(rightVal);
node.right = rightNode;

queue.offer(rightNode);
}
}

return root;
}

public static String[] toTestArray(Node root) {
if (root == null) {
return new String[0];
}

java.util.LinkedList<String> list = new java.util.LinkedList<>();
Node node = root;
while (node != null) {
Node p = node;
while (p != null) {
list.add("" + p.val);

p = p.next;
}
list.add("#");

node = node.left;
}

return list.toArray(new String[0]);
}
}
}

class TestMain {

public static void main(String[] args) {
TestUtils.runTestCases(TestCase.class);
}

public static class TestCase {

public static boolean testCase1() {
Integer[] nums = { 1, 2, 3, 4, 5, null, 7 };

Solution.Node tree = Solution.Node.genTree(nums);
Solution.Node node = new Solution().connect(tree);
String[] result = Solution.Node.toTestArray(node);
String expect = "[1, #, 2, 3, #, 4, 5, 7, #]";

return TestUtils.check(result, expect);
}

public static boolean testCase2() {
Integer[] nums = {};

Solution.Node tree = Solution.Node.genTree(nums);
Solution.Node node = new Solution().connect(tree);
String[] result = Solution.Node.toTestArray(node);
String expect = "[]";

return TestUtils.check(result, expect);
}

public static boolean testCase3() {
Integer[] nums = { 1, 2, null, 3, null, 4, null, 5 };

Solution.Node tree = Solution.Node.genTree(nums);
Solution.Node node = new Solution().connect(tree);
String[] result = Solution.Node.toTestArray(node);
String expect = "[1, #, 2, #, 3, #, 4, #, 5, #]";

return TestUtils.check(result, expect);
}
}

public static class TestUtils {

public static boolean check(Object result, Object expect) {
result = normalizeObject(result);
expect = normalizeObject(expect);
boolean ok = java.util.Objects.deepEquals(result, expect);
printCheck(toString(result), toString(expect), ok);
return ok;
}

public static boolean check(Object result, String expect) {
boolean ok = java.util.Objects.equals(normalizeString(toString(result)),
normalizeString(toString(expect)));
printCheck(normalizeString(toString(result)), normalizeString(toString(expect)), ok);
return ok;
}

private static Object normalizeObject(Object o) {
if (o instanceof java.util.List) {
java.util.List<?> list = (java.util.List<?>) o;
if (list != null && !list.isEmpty() && list.get(0) instanceof java.util.List) {
o = toArrays(list);
} else {
o = toArray(list);
}
}

return o;
}

private static String toString(Object o) {
if (o instanceof Object[]) {
return java.util.Arrays.deepToString((Object[]) o);
} else if (o instanceof int[]) {
return java.util.Arrays.toString((int[]) o);
} else if (o instanceof double[]) {
return java.util.Arrays.toString((double[]) o);
} else if (o instanceof char[]) {
return java.util.Arrays.toString((char[]) o);
} else {
return java.util.Objects.toString(o);
}
}

private static String normalizeString(String s) {
boolean isArray = (s.startsWith("{") && s.endsWith("}")) || (s.startsWith("[") && s.endsWith("]"));
if (isArray) {
s = s.replace(" ", "")
.replace("'", "")
.replace("\"", "")
.replace("{", "[")
.replace("}", "]");
}

return s;
}

private static void printCheck(String result, String expect, boolean ok) {
// System.out.println();
// System.out.println("--->");

System.out.println("result: " + result);
System.out.println("expect: " + expect);

System.out.println();
if (ok) {
System.out.println("比较结果为: 正确(right)");
} else {
System.out.println("比较结果为: 错误(error)");
}

// System.out.println();
// System.out.println("<---");
}

public static void runTestCases(Class<?> clazz) {
java.lang.reflect.Method[] methods = clazz.getDeclaredMethods();
java.util.Arrays.sort(methods, (o1, o2) -> {
return o1.getName().compareTo(o2.getName());
});
for (java.lang.reflect.Method method : methods) {
if (method.getName().startsWith("test")) {
System.out.println(String.format("--- %s --->", method.getName()));

Object object = null;
try {
object = method.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println(String.format("<--- %s ---", method.getName()));

if (object instanceof Boolean) {
Boolean ok = (Boolean) object;
if (!ok) {
break;
}
} else {
throw new RuntimeException(String.format("测试用例方法%s的返回值需要为布尔类型", method.getName()));
}
}
}
}

public static Object[] toArray(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0];
}

return list.toArray();
}

public static Object[][] toArrays(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0][0];
}

Object[][] arrays = new Object[list.size()][];
for (int i = 0; i < list.size(); i++) {
arrays[i] = toArray(list.get(i));
}

return arrays;
}

@SuppressWarnings("unchecked")
public static <T> T[] genArray(Class<T> clazz, int length) {
return (T[]) java.lang.reflect.Array.newInstance(clazz, length);
}

@SuppressWarnings("unchecked")
public static <T> T[][] genArrays(Class<T> clazz, int rows, int cols) {
T[] array = genArray(clazz, 0);

T[][] arrays = (T[][]) genArray(array.getClass(), rows);
for (int i = 0; i < arrays.length; i++) {
arrays[i] = genArray(clazz, cols);
}

return arrays;
}

public static <T> T[] toArray(java.util.List<T> list, Class<T> clazz) {
if (list == null || list.isEmpty()) {
return genArray(clazz, 0);
}

T[] array = genArray(clazz, list.size());
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}

return array;
}

public static <T> T[][] toArrays(java.util.List<java.util.List<T>> lists, Class<T> clazz) {
if (lists == null || lists.isEmpty()) {
return genArrays(clazz, 0, 0);
}

T[][] arrays = genArrays(clazz, lists.size(), 0);
for (int i = 0; i < lists.size(); i++) {
arrays[i] = toArray(lists.get(i), clazz);
}

return arrays;
}

public static <T> java.util.List<T> toList(T[] array) {
return java.util.Arrays.asList(array);
}

public static <T> java.util.List<java.util.List<T>> toLists(T[][] arrays) {
java.util.List<java.util.List<T>> lists = new java.util.ArrayList<>();
for (T[] array : arrays) {
lists.add(toList(array));
}

return lists;
}
}
}

其他解法

解法1

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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;

public class Solution {
public Node connect(Node root) {
if (root == null) {
return null;
}

Node preNode = null; // 存储层次遍历的上一个结点
Map<Node, Integer> map = new HashMap<>(); // 存储每个结点的深度

map.put(preNode, 0);
map.put(root, 1);

Queue<Node> queue = new LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
Node node = queue.poll();

if (node.left != null) {
queue.offer(node.left);

map.put(node.left, map.get(node) + 1);
}

if (node.right != null) {
queue.offer(node.right);

map.put(node.right, map.get(node) + 1);
}

if (preNode != null && map.get(node) == map.get(preNode)) {
preNode.next = node;
}

preNode = node;
}

return root;
}

static class Node {
public int val;
public Node left;
public Node right;
public Node next;

public Node() {
}

public Node(int _val) {
val = _val;
}

public Node(int _val, Node _left, Node _right, Node _next) {
val = _val;
left = _left;
right = _right;
next = _next;
}

public static Node genTree(Integer[] nums) {
if (nums.length == 0) {
return null;
}

java.util.Queue<Node> queue = new java.util.LinkedList<>();
Node root = new Node(nums[0]);
queue.offer(root);

int i = 1;
while (i < nums.length) {
Node node = queue.poll();

Integer leftVal = i < nums.length ? nums[i++] : null;
if (leftVal != null) {
Node leftNode = new Node(leftVal);
node.left = leftNode;

queue.offer(leftNode);
}

Integer rightVal = i < nums.length ? nums[i++] : null;
if (rightVal != null) {
Node rightNode = new Node(rightVal);
node.right = rightNode;

queue.offer(rightNode);
}
}

return root;
}

public static String[] toTestArray(Node root) {
if (root == null) {
return new String[0];
}

java.util.LinkedList<String> list = new java.util.LinkedList<>();
Node node = root;
while (node != null) {
Node p = node;
while (p != null) {
list.add("" + p.val);

p = p.next;
}
list.add("#");

node = node.left;
}

return list.toArray(new String[0]);
}
}
}

class TestMain {

public static void main(String[] args) {
TestUtils.runTestCases(TestCase.class);
}

public static class TestCase {

public static boolean testCase1() {
Integer[] nums = { 1, 2, 3, 4, 5, null, 7 };

Solution.Node tree = Solution.Node.genTree(nums);
Solution.Node node = new Solution().connect(tree);
String[] result = Solution.Node.toTestArray(node);
String expect = "[1, #, 2, 3, #, 4, 5, 7, #]";

return TestUtils.check(result, expect);
}

public static boolean testCase2() {
Integer[] nums = {};

Solution.Node tree = Solution.Node.genTree(nums);
Solution.Node node = new Solution().connect(tree);
String[] result = Solution.Node.toTestArray(node);
String expect = "[]";

return TestUtils.check(result, expect);
}

public static boolean testCase3() {
Integer[] nums = { 1, 2, null, 3, null, 4, null, 5 };

Solution.Node tree = Solution.Node.genTree(nums);
Solution.Node node = new Solution().connect(tree);
String[] result = Solution.Node.toTestArray(node);
String expect = "[1, #, 2, #, 3, #, 4, #, 5, #]";

return TestUtils.check(result, expect);
}
}

public static class TestUtils {

public static boolean check(Object result, Object expect) {
result = normalizeObject(result);
expect = normalizeObject(expect);
boolean ok = java.util.Objects.deepEquals(result, expect);
printCheck(toString(result), toString(expect), ok);
return ok;
}

public static boolean check(Object result, String expect) {
boolean ok = java.util.Objects.equals(normalizeString(toString(result)),
normalizeString(toString(expect)));
printCheck(normalizeString(toString(result)), normalizeString(toString(expect)), ok);
return ok;
}

private static Object normalizeObject(Object o) {
if (o instanceof java.util.List) {
java.util.List<?> list = (java.util.List<?>) o;
if (list != null && !list.isEmpty() && list.get(0) instanceof java.util.List) {
o = toArrays(list);
} else {
o = toArray(list);
}
}

return o;
}

private static String toString(Object o) {
if (o instanceof Object[]) {
return java.util.Arrays.deepToString((Object[]) o);
} else if (o instanceof int[]) {
return java.util.Arrays.toString((int[]) o);
} else if (o instanceof double[]) {
return java.util.Arrays.toString((double[]) o);
} else if (o instanceof char[]) {
return java.util.Arrays.toString((char[]) o);
} else {
return java.util.Objects.toString(o);
}
}

private static String normalizeString(String s) {
boolean isArray = (s.startsWith("{") && s.endsWith("}")) || (s.startsWith("[") && s.endsWith("]"));
if (isArray) {
s = s.replace(" ", "")
.replace("'", "")
.replace("\"", "")
.replace("{", "[")
.replace("}", "]");
}

return s;
}

private static void printCheck(String result, String expect, boolean ok) {
// System.out.println();
// System.out.println("--->");

System.out.println("result: " + result);
System.out.println("expect: " + expect);

System.out.println();
if (ok) {
System.out.println("比较结果为: 正确(right)");
} else {
System.out.println("比较结果为: 错误(error)");
}

// System.out.println();
// System.out.println("<---");
}

public static void runTestCases(Class<?> clazz) {
java.lang.reflect.Method[] methods = clazz.getDeclaredMethods();
java.util.Arrays.sort(methods, (o1, o2) -> {
return o1.getName().compareTo(o2.getName());
});
for (java.lang.reflect.Method method : methods) {
if (method.getName().startsWith("test")) {
System.out.println(String.format("--- %s --->", method.getName()));

Object object = null;
try {
object = method.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println(String.format("<--- %s ---", method.getName()));

if (object instanceof Boolean) {
Boolean ok = (Boolean) object;
if (!ok) {
break;
}
} else {
throw new RuntimeException(String.format("测试用例方法%s的返回值需要为布尔类型", method.getName()));
}
}
}
}

public static Object[] toArray(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0];
}

return list.toArray();
}

public static Object[][] toArrays(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0][0];
}

Object[][] arrays = new Object[list.size()][];
for (int i = 0; i < list.size(); i++) {
arrays[i] = toArray(list.get(i));
}

return arrays;
}

@SuppressWarnings("unchecked")
public static <T> T[] genArray(Class<T> clazz, int length) {
return (T[]) java.lang.reflect.Array.newInstance(clazz, length);
}

@SuppressWarnings("unchecked")
public static <T> T[][] genArrays(Class<T> clazz, int rows, int cols) {
T[] array = genArray(clazz, 0);

T[][] arrays = (T[][]) genArray(array.getClass(), rows);
for (int i = 0; i < arrays.length; i++) {
arrays[i] = genArray(clazz, cols);
}

return arrays;
}

public static <T> T[] toArray(java.util.List<T> list, Class<T> clazz) {
if (list == null || list.isEmpty()) {
return genArray(clazz, 0);
}

T[] array = genArray(clazz, list.size());
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}

return array;
}

public static <T> T[][] toArrays(java.util.List<java.util.List<T>> lists, Class<T> clazz) {
if (lists == null || lists.isEmpty()) {
return genArrays(clazz, 0, 0);
}

T[][] arrays = genArrays(clazz, lists.size(), 0);
for (int i = 0; i < lists.size(); i++) {
arrays[i] = toArray(lists.get(i), clazz);
}

return arrays;
}

public static <T> java.util.List<T> toList(T[] array) {
return java.util.Arrays.asList(array);
}

public static <T> java.util.List<java.util.List<T>> toLists(T[][] arrays) {
java.util.List<java.util.List<T>> lists = new java.util.ArrayList<>();
for (T[] array : arrays) {
lists.add(toList(array));
}

return lists;
}
}
}

二叉树展开为链表

题目描述

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
给你二叉树的根结点 root ,请你将它展开为一个单链表:

展开后的单链表应该同样使用 TreeNode ,其中 right 子指针指向链表中下一个结点,而左子指针始终为 null 。
展开后的单链表应该与二叉树 先序遍历 顺序相同。


示例 1:

输入:root = [1,2,5,3,4,null,6]
输出:[1,null,2,null,3,null,4,null,5,null,6]
示例 2:

输入:root = []
输出:[]
示例 3:

输入:root = [0]
输出:[0]


提示:

树中结点数在范围 [0, 2000] 内
-100 <= Node.val <= 100


进阶:你可以使用原地算法(O(1) 额外空间)展开这棵树吗?

题目解答

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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
public class Solution {
private TreeNode dummyNode = new TreeNode(0);
private TreeNode tailNode = dummyNode;

public void flatten(TreeNode root) {
if (root == null) {
return;
}

TreeNode left = root.left;
TreeNode right = root.right;

// 先序遍历时处理结点
// 使用尾插法插入新链表
root.left = null;
root.right = null;
tailNode.right = root;
tailNode = root;

flatten(left);
flatten(right);

// 递归调用会导致多次清理,所以要判空
if (dummyNode != null) {
dummyNode.right = null;
dummyNode = null;
}
}

static class TreeNode {
int val;
TreeNode left;
TreeNode right;

TreeNode() {
}

TreeNode(int val) {
this.val = val;
}

TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}

public static TreeNode genTree(Integer[] array) {
if (array.length == 0) {
return null;
}

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
TreeNode root = new TreeNode(array[0]);
queue.offer(root);

Integer v = null;
int i = 1;
while (i < array.length) {
TreeNode node = queue.poll();

TreeNode left = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;
TreeNode right = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;

// 数组中不包含空节点的子节点的写法(不标准的完全二叉树含空节点的层次遍历)
node.left = left;
node.right = right;
if (left != null) {
queue.offer(left);
}
if (right != null) {
queue.offer(right);
}

// 数组中包含空节点的子节点的写法(标准的完全二叉树含空节点的层次遍历)
// if (node != null) {
// node.left = left;
// node.right = right;
// }
// queue.offer(left);
// queue.offer(right);
}

return root;
}

public static Integer[] toArray(TreeNode root) {
if (root == null) {
return new Integer[0];
}

java.util.LinkedList<Integer> list = new java.util.LinkedList<>();

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
boolean hasValidNode = false;

int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();

if (node != null) {
list.add(node.val);

queue.offer(node.left);
queue.offer(node.right);

if (!hasValidNode) {
hasValidNode = node.left != null || node.right != null;
}
} else {
list.add(null);
}
}

if (!hasValidNode) {
// while (!queue.isEmpty()) {
// queue.poll();
// }

break;
}
}

while (!list.isEmpty() && list.get(list.size() - 1) == null) {
list.remove(list.size() - 1);
}

return list.toArray(new Integer[0]);
}
}
}

class TestMain {

public static void main(String[] args) {
TestUtils.runTestCases(TestCase.class);
}

public static class TestCase {

public static boolean testCase1() {
Integer[] nums = { 1, 2, 5, 3, 4, null, 6 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
new Solution().flatten(tree);
Integer[] result = Solution.TreeNode.toArray(tree);
Integer[] expect = { 1, null, 2, null, 3, null, 4, null, 5, null, 6 };

return TestUtils.check(result, expect);
}

public static boolean testCase2() {
Integer[] nums = {};

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
new Solution().flatten(tree);
Integer[] result = Solution.TreeNode.toArray(tree);
Integer[] expect = {};

return TestUtils.check(result, expect);
}

public static boolean testCase3() {
Integer[] nums = { 0 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
new Solution().flatten(tree);
Integer[] result = Solution.TreeNode.toArray(tree);
Integer[] expect = { 0 };

return TestUtils.check(result, expect);
}
}

public static class TestUtils {

public static boolean check(Object result, Object expect) {
result = normalizeObject(result);
expect = normalizeObject(expect);
boolean ok = java.util.Objects.deepEquals(result, expect);
printCheck(toString(result), toString(expect), ok);
return ok;
}

public static boolean check(Object result, String expect) {
boolean ok = java.util.Objects.equals(normalizeString(toString(result)),
normalizeString(toString(expect)));
printCheck(normalizeString(toString(result)), normalizeString(toString(expect)), ok);
return ok;
}

private static Object normalizeObject(Object o) {
if (o instanceof java.util.List) {
java.util.List<?> list = (java.util.List<?>) o;
if (list != null && !list.isEmpty() && list.get(0) instanceof java.util.List) {
o = toArrays(list);
} else {
o = toArray(list);
}
}

return o;
}

private static String toString(Object o) {
if (o instanceof Object[]) {
return java.util.Arrays.deepToString((Object[]) o);
} else if (o instanceof int[]) {
return java.util.Arrays.toString((int[]) o);
} else if (o instanceof double[]) {
return java.util.Arrays.toString((double[]) o);
} else if (o instanceof char[]) {
return java.util.Arrays.toString((char[]) o);
} else {
return java.util.Objects.toString(o);
}
}

private static String normalizeString(String s) {
boolean isArray = (s.startsWith("{") && s.endsWith("}")) || (s.startsWith("[") && s.endsWith("]"));
if (isArray) {
s = s.replace(" ", "")
.replace("'", "")
.replace("\"", "")
.replace("{", "[")
.replace("}", "]");
}

return s;
}

private static void printCheck(String result, String expect, boolean ok) {
// System.out.println();
// System.out.println("--->");

System.out.println("result: " + result);
System.out.println("expect: " + expect);

System.out.println();
if (ok) {
System.out.println("比较结果为: 正确(right)");
} else {
System.out.println("比较结果为: 错误(error)");
}

// System.out.println();
// System.out.println("<---");
}

public static void runTestCases(Class<?> clazz) {
java.lang.reflect.Method[] methods = clazz.getDeclaredMethods();
java.util.Arrays.sort(methods, (o1, o2) -> {
return o1.getName().compareTo(o2.getName());
});
for (java.lang.reflect.Method method : methods) {
if (method.getName().startsWith("test")) {
System.out.println(String.format("--- %s --->", method.getName()));

Object object = null;
try {
object = method.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println(String.format("<--- %s ---", method.getName()));

if (object instanceof Boolean) {
Boolean ok = (Boolean) object;
if (!ok) {
break;
}
} else {
throw new RuntimeException(String.format("测试用例方法%s的返回值需要为布尔类型", method.getName()));
}
}
}
}

public static Object[] toArray(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0];
}

return list.toArray();
}

public static Object[][] toArrays(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0][0];
}

Object[][] arrays = new Object[list.size()][];
for (int i = 0; i < list.size(); i++) {
arrays[i] = toArray(list.get(i));
}

return arrays;
}

@SuppressWarnings("unchecked")
public static <T> T[] genArray(Class<T> clazz, int length) {
return (T[]) java.lang.reflect.Array.newInstance(clazz, length);
}

@SuppressWarnings("unchecked")
public static <T> T[][] genArrays(Class<T> clazz, int rows, int cols) {
T[] array = genArray(clazz, 0);

T[][] arrays = (T[][]) genArray(array.getClass(), rows);
for (int i = 0; i < arrays.length; i++) {
arrays[i] = genArray(clazz, cols);
}

return arrays;
}

public static <T> T[] toArray(java.util.List<T> list, Class<T> clazz) {
if (list == null || list.isEmpty()) {
return genArray(clazz, 0);
}

T[] array = genArray(clazz, list.size());
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}

return array;
}

public static <T> T[][] toArrays(java.util.List<java.util.List<T>> lists, Class<T> clazz) {
if (lists == null || lists.isEmpty()) {
return genArrays(clazz, 0, 0);
}

T[][] arrays = genArrays(clazz, lists.size(), 0);
for (int i = 0; i < lists.size(); i++) {
arrays[i] = toArray(lists.get(i), clazz);
}

return arrays;
}

public static <T> java.util.List<T> toList(T[] array) {
return java.util.Arrays.asList(array);
}

public static <T> java.util.List<java.util.List<T>> toLists(T[][] arrays) {
java.util.List<java.util.List<T>> lists = new java.util.ArrayList<>();
for (T[] array : arrays) {
lists.add(toList(array));
}

return lists;
}
}
}

进阶解法

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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
import java.util.Deque;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;

public class Solution {
public void flatten(TreeNode root) {
if (root == null) {
return;
}

TreeNode dummyNode = new TreeNode(0);
TreeNode tailNode = dummyNode;

// Map<TreeNode, TreeNode> map1 = new HashMap<>(); // 记录结点的左子节点
Map<TreeNode, TreeNode> map2 = new HashMap<>(); // 记录结点的右子节点

Deque<TreeNode> stack = new LinkedList<>();

TreeNode p = root;
while (p != null || !stack.isEmpty()) {
if (p != null) {
// 节点的左指针和右指针会在下面被修改为指向其他地方
// 需要先保存下来,否则后续的遍历无法进行
// map1.put(p, p.left); // 保存结点的左子节点
map2.put(p, p.right); // 保存结点的右子节点
TreeNode left = p.left; // 保存结点的左子节点

// 先序遍历时处理结点
// 使用尾插法插入新链表
TreeNode node = p;
node.left = null;
node.right = null;
tailNode.right = node;
tailNode = node;

stack.push(p);
// p = p.left;
// // p.left已经被破坏,需要从map里面找
// p = map1.get(p);
// p.left已经被破坏,用保存好的left
p = left;
} else {
p = stack.pop();
// p = p.right;
// p.right已经被破坏,需要从map里面找
p = map2.get(p);
}
}

dummyNode.right = null;
dummyNode = null;
}

static class TreeNode {
int val;
TreeNode left;
TreeNode right;

TreeNode() {
}

TreeNode(int val) {
this.val = val;
}

TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}

public static TreeNode genTree(Integer[] array) {
if (array.length == 0) {
return null;
}

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
TreeNode root = new TreeNode(array[0]);
queue.offer(root);

Integer v = null;
int i = 1;
while (i < array.length) {
TreeNode node = queue.poll();

TreeNode left = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;
TreeNode right = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;

// 数组中不包含空节点的子节点的写法(不标准的完全二叉树含空节点的层次遍历)
node.left = left;
node.right = right;
if (left != null) {
queue.offer(left);
}
if (right != null) {
queue.offer(right);
}

// 数组中包含空节点的子节点的写法(标准的完全二叉树含空节点的层次遍历)
// if (node != null) {
// node.left = left;
// node.right = right;
// }
// queue.offer(left);
// queue.offer(right);
}

return root;
}

public static Integer[] toArray(TreeNode root) {
if (root == null) {
return new Integer[0];
}

java.util.LinkedList<Integer> list = new java.util.LinkedList<>();

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
boolean hasValidNode = false;

int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();

if (node != null) {
list.add(node.val);

queue.offer(node.left);
queue.offer(node.right);

if (!hasValidNode) {
hasValidNode = node.left != null || node.right != null;
}
} else {
list.add(null);
}
}

if (!hasValidNode) {
// while (!queue.isEmpty()) {
// queue.poll();
// }

break;
}
}

while (!list.isEmpty() && list.get(list.size() - 1) == null) {
list.remove(list.size() - 1);
}

return list.toArray(new Integer[0]);
}
}
}

class TestMain {

public static void main(String[] args) {
TestUtils.runTestCases(TestCase.class);
}

public static class TestCase {

public static boolean testCase1() {
Integer[] nums = { 1, 2, 5, 3, 4, null, 6 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
new Solution().flatten(tree);
Integer[] result = Solution.TreeNode.toArray(tree);
Integer[] expect = { 1, null, 2, null, 3, null, 4, null, 5, null, 6 };

return TestUtils.check(result, expect);
}

public static boolean testCase2() {
Integer[] nums = {};

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
new Solution().flatten(tree);
Integer[] result = Solution.TreeNode.toArray(tree);
Integer[] expect = {};

return TestUtils.check(result, expect);
}

public static boolean testCase3() {
Integer[] nums = { 0 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
new Solution().flatten(tree);
Integer[] result = Solution.TreeNode.toArray(tree);
Integer[] expect = { 0 };

return TestUtils.check(result, expect);
}
}

public static class TestUtils {

public static boolean check(Object result, Object expect) {
result = normalizeObject(result);
expect = normalizeObject(expect);
boolean ok = java.util.Objects.deepEquals(result, expect);
printCheck(toString(result), toString(expect), ok);
return ok;
}

public static boolean check(Object result, String expect) {
boolean ok = java.util.Objects.equals(normalizeString(toString(result)),
normalizeString(toString(expect)));
printCheck(normalizeString(toString(result)), normalizeString(toString(expect)), ok);
return ok;
}

private static Object normalizeObject(Object o) {
if (o instanceof java.util.List) {
java.util.List<?> list = (java.util.List<?>) o;
if (list != null && !list.isEmpty() && list.get(0) instanceof java.util.List) {
o = toArrays(list);
} else {
o = toArray(list);
}
}

return o;
}

private static String toString(Object o) {
if (o instanceof Object[]) {
return java.util.Arrays.deepToString((Object[]) o);
} else if (o instanceof int[]) {
return java.util.Arrays.toString((int[]) o);
} else if (o instanceof double[]) {
return java.util.Arrays.toString((double[]) o);
} else if (o instanceof char[]) {
return java.util.Arrays.toString((char[]) o);
} else {
return java.util.Objects.toString(o);
}
}

private static String normalizeString(String s) {
boolean isArray = (s.startsWith("{") && s.endsWith("}")) || (s.startsWith("[") && s.endsWith("]"));
if (isArray) {
s = s.replace(" ", "")
.replace("'", "")
.replace("\"", "")
.replace("{", "[")
.replace("}", "]");
}

return s;
}

private static void printCheck(String result, String expect, boolean ok) {
// System.out.println();
// System.out.println("--->");

System.out.println("result: " + result);
System.out.println("expect: " + expect);

System.out.println();
if (ok) {
System.out.println("比较结果为: 正确(right)");
} else {
System.out.println("比较结果为: 错误(error)");
}

// System.out.println();
// System.out.println("<---");
}

public static void runTestCases(Class<?> clazz) {
java.lang.reflect.Method[] methods = clazz.getDeclaredMethods();
java.util.Arrays.sort(methods, (o1, o2) -> {
return o1.getName().compareTo(o2.getName());
});
for (java.lang.reflect.Method method : methods) {
if (method.getName().startsWith("test")) {
System.out.println(String.format("--- %s --->", method.getName()));

Object object = null;
try {
object = method.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println(String.format("<--- %s ---", method.getName()));

if (object instanceof Boolean) {
Boolean ok = (Boolean) object;
if (!ok) {
break;
}
} else {
throw new RuntimeException(String.format("测试用例方法%s的返回值需要为布尔类型", method.getName()));
}
}
}
}

public static Object[] toArray(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0];
}

return list.toArray();
}

public static Object[][] toArrays(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0][0];
}

Object[][] arrays = new Object[list.size()][];
for (int i = 0; i < list.size(); i++) {
arrays[i] = toArray(list.get(i));
}

return arrays;
}

@SuppressWarnings("unchecked")
public static <T> T[] genArray(Class<T> clazz, int length) {
return (T[]) java.lang.reflect.Array.newInstance(clazz, length);
}

@SuppressWarnings("unchecked")
public static <T> T[][] genArrays(Class<T> clazz, int rows, int cols) {
T[] array = genArray(clazz, 0);

T[][] arrays = (T[][]) genArray(array.getClass(), rows);
for (int i = 0; i < arrays.length; i++) {
arrays[i] = genArray(clazz, cols);
}

return arrays;
}

public static <T> T[] toArray(java.util.List<T> list, Class<T> clazz) {
if (list == null || list.isEmpty()) {
return genArray(clazz, 0);
}

T[] array = genArray(clazz, list.size());
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}

return array;
}

public static <T> T[][] toArrays(java.util.List<java.util.List<T>> lists, Class<T> clazz) {
if (lists == null || lists.isEmpty()) {
return genArrays(clazz, 0, 0);
}

T[][] arrays = genArrays(clazz, lists.size(), 0);
for (int i = 0; i < lists.size(); i++) {
arrays[i] = toArray(lists.get(i), clazz);
}

return arrays;
}

public static <T> java.util.List<T> toList(T[] array) {
return java.util.Arrays.asList(array);
}

public static <T> java.util.List<java.util.List<T>> toLists(T[][] arrays) {
java.util.List<java.util.List<T>> lists = new java.util.ArrayList<>();
for (T[] array : arrays) {
lists.add(toList(array));
}

return lists;
}
}
}

其他解法

解法1

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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
import java.util.Deque;
import java.util.LinkedList;
import java.util.List;

public class Solution {
public void flatten(TreeNode root) {
if (root == null) {
return;
}

TreeNode dummyNode = new TreeNode(0);
TreeNode tailNode = dummyNode;

List<TreeNode> list = new LinkedList<>();

Deque<TreeNode> stack = new LinkedList<>();

TreeNode p = root;
while (p != null || !stack.isEmpty()) {
if (p != null) {
// 先序遍历时处理结点
// 用list搜集起来
list.add(p);

stack.push(p);
p = p.left;
} else {
p = stack.pop();
p = p.right;
}
}

// 使用尾插法插入新链表
for (TreeNode node : list) {
node.left = null;
node.right = null;
tailNode.right = node;
tailNode = node;
}

dummyNode.right = null;
dummyNode = null;
}

static class TreeNode {
int val;
TreeNode left;
TreeNode right;

TreeNode() {
}

TreeNode(int val) {
this.val = val;
}

TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}

public static TreeNode genTree(Integer[] array) {
if (array.length == 0) {
return null;
}

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
TreeNode root = new TreeNode(array[0]);
queue.offer(root);

Integer v = null;
int i = 1;
while (i < array.length) {
TreeNode node = queue.poll();

TreeNode left = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;
TreeNode right = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;

// 数组中不包含空节点的子节点的写法(不标准的完全二叉树含空节点的层次遍历)
node.left = left;
node.right = right;
if (left != null) {
queue.offer(left);
}
if (right != null) {
queue.offer(right);
}

// 数组中包含空节点的子节点的写法(标准的完全二叉树含空节点的层次遍历)
// if (node != null) {
// node.left = left;
// node.right = right;
// }
// queue.offer(left);
// queue.offer(right);
}

return root;
}

public static Integer[] toArray(TreeNode root) {
if (root == null) {
return new Integer[0];
}

java.util.LinkedList<Integer> list = new java.util.LinkedList<>();

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
boolean hasValidNode = false;

int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();

if (node != null) {
list.add(node.val);

queue.offer(node.left);
queue.offer(node.right);

if (!hasValidNode) {
hasValidNode = node.left != null || node.right != null;
}
} else {
list.add(null);
}
}

if (!hasValidNode) {
// while (!queue.isEmpty()) {
// queue.poll();
// }

break;
}
}

while (!list.isEmpty() && list.get(list.size() - 1) == null) {
list.remove(list.size() - 1);
}

return list.toArray(new Integer[0]);
}
}
}

class TestMain {

public static void main(String[] args) {
TestUtils.runTestCases(TestCase.class);
}

public static class TestCase {

public static boolean testCase1() {
Integer[] nums = { 1, 2, 5, 3, 4, null, 6 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
new Solution().flatten(tree);
Integer[] result = Solution.TreeNode.toArray(tree);
Integer[] expect = { 1, null, 2, null, 3, null, 4, null, 5, null, 6 };

return TestUtils.check(result, expect);
}

public static boolean testCase2() {
Integer[] nums = {};

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
new Solution().flatten(tree);
Integer[] result = Solution.TreeNode.toArray(tree);
Integer[] expect = {};

return TestUtils.check(result, expect);
}

public static boolean testCase3() {
Integer[] nums = { 0 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
new Solution().flatten(tree);
Integer[] result = Solution.TreeNode.toArray(tree);
Integer[] expect = { 0 };

return TestUtils.check(result, expect);
}
}

public static class TestUtils {

public static boolean check(Object result, Object expect) {
result = normalizeObject(result);
expect = normalizeObject(expect);
boolean ok = java.util.Objects.deepEquals(result, expect);
printCheck(toString(result), toString(expect), ok);
return ok;
}

public static boolean check(Object result, String expect) {
boolean ok = java.util.Objects.equals(normalizeString(toString(result)),
normalizeString(toString(expect)));
printCheck(normalizeString(toString(result)), normalizeString(toString(expect)), ok);
return ok;
}

private static Object normalizeObject(Object o) {
if (o instanceof java.util.List) {
java.util.List<?> list = (java.util.List<?>) o;
if (list != null && !list.isEmpty() && list.get(0) instanceof java.util.List) {
o = toArrays(list);
} else {
o = toArray(list);
}
}

return o;
}

private static String toString(Object o) {
if (o instanceof Object[]) {
return java.util.Arrays.deepToString((Object[]) o);
} else if (o instanceof int[]) {
return java.util.Arrays.toString((int[]) o);
} else if (o instanceof double[]) {
return java.util.Arrays.toString((double[]) o);
} else if (o instanceof char[]) {
return java.util.Arrays.toString((char[]) o);
} else {
return java.util.Objects.toString(o);
}
}

private static String normalizeString(String s) {
boolean isArray = (s.startsWith("{") && s.endsWith("}")) || (s.startsWith("[") && s.endsWith("]"));
if (isArray) {
s = s.replace(" ", "")
.replace("'", "")
.replace("\"", "")
.replace("{", "[")
.replace("}", "]");
}

return s;
}

private static void printCheck(String result, String expect, boolean ok) {
// System.out.println();
// System.out.println("--->");

System.out.println("result: " + result);
System.out.println("expect: " + expect);

System.out.println();
if (ok) {
System.out.println("比较结果为: 正确(right)");
} else {
System.out.println("比较结果为: 错误(error)");
}

// System.out.println();
// System.out.println("<---");
}

public static void runTestCases(Class<?> clazz) {
java.lang.reflect.Method[] methods = clazz.getDeclaredMethods();
java.util.Arrays.sort(methods, (o1, o2) -> {
return o1.getName().compareTo(o2.getName());
});
for (java.lang.reflect.Method method : methods) {
if (method.getName().startsWith("test")) {
System.out.println(String.format("--- %s --->", method.getName()));

Object object = null;
try {
object = method.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println(String.format("<--- %s ---", method.getName()));

if (object instanceof Boolean) {
Boolean ok = (Boolean) object;
if (!ok) {
break;
}
} else {
throw new RuntimeException(String.format("测试用例方法%s的返回值需要为布尔类型", method.getName()));
}
}
}
}

public static Object[] toArray(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0];
}

return list.toArray();
}

public static Object[][] toArrays(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0][0];
}

Object[][] arrays = new Object[list.size()][];
for (int i = 0; i < list.size(); i++) {
arrays[i] = toArray(list.get(i));
}

return arrays;
}

@SuppressWarnings("unchecked")
public static <T> T[] genArray(Class<T> clazz, int length) {
return (T[]) java.lang.reflect.Array.newInstance(clazz, length);
}

@SuppressWarnings("unchecked")
public static <T> T[][] genArrays(Class<T> clazz, int rows, int cols) {
T[] array = genArray(clazz, 0);

T[][] arrays = (T[][]) genArray(array.getClass(), rows);
for (int i = 0; i < arrays.length; i++) {
arrays[i] = genArray(clazz, cols);
}

return arrays;
}

public static <T> T[] toArray(java.util.List<T> list, Class<T> clazz) {
if (list == null || list.isEmpty()) {
return genArray(clazz, 0);
}

T[] array = genArray(clazz, list.size());
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}

return array;
}

public static <T> T[][] toArrays(java.util.List<java.util.List<T>> lists, Class<T> clazz) {
if (lists == null || lists.isEmpty()) {
return genArrays(clazz, 0, 0);
}

T[][] arrays = genArrays(clazz, lists.size(), 0);
for (int i = 0; i < lists.size(); i++) {
arrays[i] = toArray(lists.get(i), clazz);
}

return arrays;
}

public static <T> java.util.List<T> toList(T[] array) {
return java.util.Arrays.asList(array);
}

public static <T> java.util.List<java.util.List<T>> toLists(T[][] arrays) {
java.util.List<java.util.List<T>> lists = new java.util.ArrayList<>();
for (T[] array : arrays) {
lists.add(toList(array));
}

return lists;
}
}
}

二叉树的所有路径

题目描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
给你一个二叉树的根节点 root ,按 任意顺序 ,返回所有从根节点到叶子节点的路径。

叶子节点 是指没有子节点的节点。


示例 1:

输入:root = [1,2,3,null,5]
输出:["1->2->5","1->3"]
示例 2:

输入:root = [1]
输出:["1"]


提示:

树中节点的数目在范围 [1, 100] 内
-100 <= Node.val <= 100

题目解答

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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

public class Solution {
private List<String> list = new LinkedList<>();
private Map<TreeNode, TreeNode> map = new HashMap<>(); // 存储每个结点到双亲结点的映射

public List<String> binaryTreePaths(TreeNode root) {
if (root == null) {
return list;
}

if (root.left == null && root.right == null) {
List<String> tmp = new LinkedList<>();

TreeNode p = root;
while (p != null) {
tmp.add(0, "" + p.val);

p = map.get(p);
}

list.add(String.join("->", tmp));
}

map.put(root.left, root);
map.put(root.right, root);

binaryTreePaths(root.left);
binaryTreePaths(root.right);

return list;
}

static class TreeNode {
int val;
TreeNode left;
TreeNode right;

TreeNode() {
}

TreeNode(int val) {
this.val = val;
}

TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}

public static TreeNode genTree(Integer[] array) {
if (array.length == 0) {
return null;
}

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
TreeNode root = new TreeNode(array[0]);
queue.offer(root);

Integer v = null;
int i = 1;
while (i < array.length) {
TreeNode node = queue.poll();

TreeNode left = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;
TreeNode right = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;

// 数组中不包含空节点的子节点的写法(不标准的完全二叉树含空节点的层次遍历)
node.left = left;
node.right = right;
if (left != null) {
queue.offer(left);
}
if (right != null) {
queue.offer(right);
}

// 数组中包含空节点的子节点的写法(标准的完全二叉树含空节点的层次遍历)
// if (node != null) {
// node.left = left;
// node.right = right;
// }
// queue.offer(left);
// queue.offer(right);
}

return root;
}

public static Integer[] toArray(TreeNode root) {
if (root == null) {
return new Integer[0];
}

java.util.LinkedList<Integer> list = new java.util.LinkedList<>();

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
boolean hasValidNode = false;

int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();

if (node != null) {
list.add(node.val);

queue.offer(node.left);
queue.offer(node.right);

if (!hasValidNode) {
hasValidNode = node.left != null || node.right != null;
}
} else {
list.add(null);
}
}

if (!hasValidNode) {
// while (!queue.isEmpty()) {
// queue.poll();
// }

break;
}
}

while (!list.isEmpty() && list.get(list.size() - 1) == null) {
list.remove(list.size() - 1);
}

return list.toArray(new Integer[0]);
}
}
}

class TestMain {

public static void main(String[] args) {
TestUtils.runTestCases(TestCase.class);
}

public static class TestCase {

public static boolean testCase1() {
Integer[] nums = { 1, 2, 3, null, 5 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<String> result = new Solution().binaryTreePaths(tree);
String[] expect = { "1->2->5", "1->3" };

return TestUtils.check(result, expect);
}

public static boolean testCase2() {
Integer[] nums = { 1 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<String> result = new Solution().binaryTreePaths(tree);
String[] expect = { "1" };

return TestUtils.check(result, expect);
}
}

public static class TestUtils {

public static boolean check(Object result, Object expect) {
result = normalizeObject(result);
expect = normalizeObject(expect);
boolean ok = java.util.Objects.deepEquals(result, expect);
printCheck(toString(result), toString(expect), ok);
return ok;
}

public static boolean check(Object result, String expect) {
boolean ok = java.util.Objects.equals(normalizeString(toString(result)),
normalizeString(toString(expect)));
printCheck(normalizeString(toString(result)), normalizeString(toString(expect)), ok);
return ok;
}

private static Object normalizeObject(Object o) {
if (o instanceof java.util.List) {
java.util.List<?> list = (java.util.List<?>) o;
if (list != null && !list.isEmpty() && list.get(0) instanceof java.util.List) {
o = toArrays(list);
} else {
o = toArray(list);
}
}

return o;
}

private static String toString(Object o) {
if (o instanceof Object[]) {
return java.util.Arrays.deepToString((Object[]) o);
} else if (o instanceof int[]) {
return java.util.Arrays.toString((int[]) o);
} else if (o instanceof double[]) {
return java.util.Arrays.toString((double[]) o);
} else if (o instanceof char[]) {
return java.util.Arrays.toString((char[]) o);
} else {
return java.util.Objects.toString(o);
}
}

private static String normalizeString(String s) {
boolean isArray = (s.startsWith("{") && s.endsWith("}")) || (s.startsWith("[") && s.endsWith("]"));
if (isArray) {
s = s.replace(" ", "")
.replace("'", "")
.replace("\"", "")
.replace("{", "[")
.replace("}", "]");
}

return s;
}

private static void printCheck(String result, String expect, boolean ok) {
// System.out.println();
// System.out.println("--->");

System.out.println("result: " + result);
System.out.println("expect: " + expect);

System.out.println();
if (ok) {
System.out.println("比较结果为: 正确(right)");
} else {
System.out.println("比较结果为: 错误(error)");
}

// System.out.println();
// System.out.println("<---");
}

public static void runTestCases(Class<?> clazz) {
java.lang.reflect.Method[] methods = clazz.getDeclaredMethods();
java.util.Arrays.sort(methods, (o1, o2) -> {
return o1.getName().compareTo(o2.getName());
});
for (java.lang.reflect.Method method : methods) {
if (method.getName().startsWith("test")) {
System.out.println(String.format("--- %s --->", method.getName()));

Object object = null;
try {
object = method.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println(String.format("<--- %s ---", method.getName()));

if (object instanceof Boolean) {
Boolean ok = (Boolean) object;
if (!ok) {
break;
}
} else {
throw new RuntimeException(String.format("测试用例方法%s的返回值需要为布尔类型", method.getName()));
}
}
}
}

public static Object[] toArray(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0];
}

return list.toArray();
}

public static Object[][] toArrays(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0][0];
}

Object[][] arrays = new Object[list.size()][];
for (int i = 0; i < list.size(); i++) {
arrays[i] = toArray(list.get(i));
}

return arrays;
}

@SuppressWarnings("unchecked")
public static <T> T[] genArray(Class<T> clazz, int length) {
return (T[]) java.lang.reflect.Array.newInstance(clazz, length);
}

@SuppressWarnings("unchecked")
public static <T> T[][] genArrays(Class<T> clazz, int rows, int cols) {
T[] array = genArray(clazz, 0);

T[][] arrays = (T[][]) genArray(array.getClass(), rows);
for (int i = 0; i < arrays.length; i++) {
arrays[i] = genArray(clazz, cols);
}

return arrays;
}

public static <T> T[] toArray(java.util.List<T> list, Class<T> clazz) {
if (list == null || list.isEmpty()) {
return genArray(clazz, 0);
}

T[] array = genArray(clazz, list.size());
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}

return array;
}

public static <T> T[][] toArrays(java.util.List<java.util.List<T>> lists, Class<T> clazz) {
if (lists == null || lists.isEmpty()) {
return genArrays(clazz, 0, 0);
}

T[][] arrays = genArrays(clazz, lists.size(), 0);
for (int i = 0; i < lists.size(); i++) {
arrays[i] = toArray(lists.get(i), clazz);
}

return arrays;
}

public static <T> java.util.List<T> toList(T[] array) {
return java.util.Arrays.asList(array);
}

public static <T> java.util.List<java.util.List<T>> toLists(T[][] arrays) {
java.util.List<java.util.List<T>> lists = new java.util.ArrayList<>();
for (T[] array : arrays) {
lists.add(toList(array));
}

return lists;
}
}
}

路径总和

题目描述

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
给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false 。

叶子节点 是指没有子节点的节点。



示例 1:

输入:root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22
输出:true
解释:等于目标和的根节点到叶节点路径如上图所示。
示例 2:

输入:root = [1,2,3], targetSum = 5
输出:false
解释:树中存在两条根节点到叶子节点的路径:
(1 --> 2): 和为 3
(1 --> 3): 和为 4
不存在 sum = 5 的根节点到叶子节点的路径。
示例 3:

输入:root = [], targetSum = 0
输出:false
解释:由于树是空的,所以不存在根节点到叶子节点的路径。


提示:

树中节点的数目在范围 [0, 5000] 内
-1000 <= Node.val <= 1000
-1000 <= targetSum <= 1000

题目解答

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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
public class Solution {
public boolean hasPathSum(TreeNode root, int targetSum) {
if (root == null) {
return false;
}

if (root.left == null && root.right == null) {
if (root.val == targetSum) {
return true;
}
}

return hasPathSum(root.left, targetSum - root.val) ||
hasPathSum(root.right, targetSum - root.val);
}

static class TreeNode {
int val;
TreeNode left;
TreeNode right;

TreeNode() {
}

TreeNode(int val) {
this.val = val;
}

TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}

public static TreeNode genTree(Integer[] array) {
if (array.length == 0) {
return null;
}

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
TreeNode root = new TreeNode(array[0]);
queue.offer(root);

Integer v = null;
int i = 1;
while (i < array.length) {
TreeNode node = queue.poll();

TreeNode left = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;
TreeNode right = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;

// 数组中不包含空节点的子节点的写法(不标准的完全二叉树含空节点的层次遍历)
node.left = left;
node.right = right;
if (left != null) {
queue.offer(left);
}
if (right != null) {
queue.offer(right);
}

// 数组中包含空节点的子节点的写法(标准的完全二叉树含空节点的层次遍历)
// if (node != null) {
// node.left = left;
// node.right = right;
// }
// queue.offer(left);
// queue.offer(right);
}

return root;
}

public static Integer[] toArray(TreeNode root) {
if (root == null) {
return new Integer[0];
}

java.util.LinkedList<Integer> list = new java.util.LinkedList<>();

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
boolean hasValidNode = false;

int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();

if (node != null) {
list.add(node.val);

queue.offer(node.left);
queue.offer(node.right);

if (!hasValidNode) {
hasValidNode = node.left != null || node.right != null;
}
} else {
list.add(null);
}
}

if (!hasValidNode) {
// while (!queue.isEmpty()) {
// queue.poll();
// }

break;
}
}

while (!list.isEmpty() && list.get(list.size() - 1) == null) {
list.remove(list.size() - 1);
}

return list.toArray(new Integer[0]);
}
}
}

class TestMain {

public static void main(String[] args) {
TestUtils.runTestCases(TestCase.class);
}

public static class TestCase {

public static boolean testCase1() {
Integer[] nums = { 5, 4, 8, 11, null, 13, 4, 7, 2, null, null, null, 1 };
int sum = 22;

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
boolean result = new Solution().hasPathSum(tree, sum);
boolean expect = true;

return TestUtils.check(result, expect);
}

public static boolean testCase2() {
Integer[] nums = { 1, 2, 3 };
int sum = 5;

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
boolean result = new Solution().hasPathSum(tree, sum);
boolean expect = false;

return TestUtils.check(result, expect);
}

public static boolean testCase3() {
Integer[] nums = {};
int sum = 0;

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
boolean result = new Solution().hasPathSum(tree, sum);
boolean expect = false;

return TestUtils.check(result, expect);
}
}

public static class TestUtils {

public static boolean check(Object result, Object expect) {
result = normalizeObject(result);
expect = normalizeObject(expect);
boolean ok = java.util.Objects.deepEquals(result, expect);
printCheck(toString(result), toString(expect), ok);
return ok;
}

public static boolean check(Object result, String expect) {
boolean ok = java.util.Objects.equals(normalizeString(toString(result)),
normalizeString(toString(expect)));
printCheck(normalizeString(toString(result)), normalizeString(toString(expect)), ok);
return ok;
}

private static Object normalizeObject(Object o) {
if (o instanceof java.util.List) {
java.util.List<?> list = (java.util.List<?>) o;
if (list != null && !list.isEmpty() && list.get(0) instanceof java.util.List) {
o = toArrays(list);
} else {
o = toArray(list);
}
}

return o;
}

private static String toString(Object o) {
if (o instanceof Object[]) {
return java.util.Arrays.deepToString((Object[]) o);
} else if (o instanceof int[]) {
return java.util.Arrays.toString((int[]) o);
} else if (o instanceof double[]) {
return java.util.Arrays.toString((double[]) o);
} else if (o instanceof char[]) {
return java.util.Arrays.toString((char[]) o);
} else {
return java.util.Objects.toString(o);
}
}

private static String normalizeString(String s) {
boolean isArray = (s.startsWith("{") && s.endsWith("}")) || (s.startsWith("[") && s.endsWith("]"));
if (isArray) {
s = s.replace(" ", "")
.replace("'", "")
.replace("\"", "")
.replace("{", "[")
.replace("}", "]");
}

return s;
}

private static void printCheck(String result, String expect, boolean ok) {
// System.out.println();
// System.out.println("--->");

System.out.println("result: " + result);
System.out.println("expect: " + expect);

System.out.println();
if (ok) {
System.out.println("比较结果为: 正确(right)");
} else {
System.out.println("比较结果为: 错误(error)");
}

// System.out.println();
// System.out.println("<---");
}

public static void runTestCases(Class<?> clazz) {
java.lang.reflect.Method[] methods = clazz.getDeclaredMethods();
java.util.Arrays.sort(methods, (o1, o2) -> {
return o1.getName().compareTo(o2.getName());
});
for (java.lang.reflect.Method method : methods) {
if (method.getName().startsWith("test")) {
System.out.println(String.format("--- %s --->", method.getName()));

Object object = null;
try {
object = method.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println(String.format("<--- %s ---", method.getName()));

if (object instanceof Boolean) {
Boolean ok = (Boolean) object;
if (!ok) {
break;
}
} else {
throw new RuntimeException(String.format("测试用例方法%s的返回值需要为布尔类型", method.getName()));
}
}
}
}

public static Object[] toArray(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0];
}

return list.toArray();
}

public static Object[][] toArrays(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0][0];
}

Object[][] arrays = new Object[list.size()][];
for (int i = 0; i < list.size(); i++) {
arrays[i] = toArray(list.get(i));
}

return arrays;
}

@SuppressWarnings("unchecked")
public static <T> T[] genArray(Class<T> clazz, int length) {
return (T[]) java.lang.reflect.Array.newInstance(clazz, length);
}

@SuppressWarnings("unchecked")
public static <T> T[][] genArrays(Class<T> clazz, int rows, int cols) {
T[] array = genArray(clazz, 0);

T[][] arrays = (T[][]) genArray(array.getClass(), rows);
for (int i = 0; i < arrays.length; i++) {
arrays[i] = genArray(clazz, cols);
}

return arrays;
}

public static <T> T[] toArray(java.util.List<T> list, Class<T> clazz) {
if (list == null || list.isEmpty()) {
return genArray(clazz, 0);
}

T[] array = genArray(clazz, list.size());
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}

return array;
}

public static <T> T[][] toArrays(java.util.List<java.util.List<T>> lists, Class<T> clazz) {
if (lists == null || lists.isEmpty()) {
return genArrays(clazz, 0, 0);
}

T[][] arrays = genArrays(clazz, lists.size(), 0);
for (int i = 0; i < lists.size(); i++) {
arrays[i] = toArray(lists.get(i), clazz);
}

return arrays;
}

public static <T> java.util.List<T> toList(T[] array) {
return java.util.Arrays.asList(array);
}

public static <T> java.util.List<java.util.List<T>> toLists(T[][] arrays) {
java.util.List<java.util.List<T>> lists = new java.util.ArrayList<>();
for (T[] array : arrays) {
lists.add(toList(array));
}

return lists;
}
}
}

路径总和II

题目描述

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
给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。

叶子节点 是指没有子节点的节点。



示例 1:

输入:root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22
输出:[[5,4,11,2],[5,8,4,5]]
示例 2:

输入:root = [1,2,3], targetSum = 5
输出:[]
示例 3:

输入:root = [1,2], targetSum = 0
输出:[]


提示:

树中节点总数在范围 [0, 5000] 内
-1000 <= Node.val <= 1000
-1000 <= targetSum <= 1000

题目解答

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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

public class Solution {
private List<List<Integer>> lists = new LinkedList<>();
private Map<TreeNode, TreeNode> map = new HashMap<>(); // 存储每个结点到双亲结点的映射

public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
if (root == null) {
return lists;
}

if (root.left == null && root.right == null) {
if (root.val == targetSum) {
List<Integer> list = new LinkedList<>();

TreeNode p = root;
while (p != null) {
list.add(0, p.val);

p = map.get(p);
}

lists.add(list);
}
}

map.put(root.left, root);
map.put(root.right, root);

pathSum(root.left, targetSum - root.val);
pathSum(root.right, targetSum - root.val);

return lists;
}

static class TreeNode {
int val;
TreeNode left;
TreeNode right;

TreeNode() {
}

TreeNode(int val) {
this.val = val;
}

TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}

public static TreeNode genTree(Integer[] array) {
if (array.length == 0) {
return null;
}

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
TreeNode root = new TreeNode(array[0]);
queue.offer(root);

Integer v = null;
int i = 1;
while (i < array.length) {
TreeNode node = queue.poll();

TreeNode left = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;
TreeNode right = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;

// 数组中不包含空节点的子节点的写法(不标准的完全二叉树含空节点的层次遍历)
node.left = left;
node.right = right;
if (left != null) {
queue.offer(left);
}
if (right != null) {
queue.offer(right);
}

// 数组中包含空节点的子节点的写法(标准的完全二叉树含空节点的层次遍历)
// if (node != null) {
// node.left = left;
// node.right = right;
// }
// queue.offer(left);
// queue.offer(right);
}

return root;
}

public static Integer[] toArray(TreeNode root) {
if (root == null) {
return new Integer[0];
}

java.util.LinkedList<Integer> list = new java.util.LinkedList<>();

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
boolean hasValidNode = false;

int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();

if (node != null) {
list.add(node.val);

queue.offer(node.left);
queue.offer(node.right);

if (!hasValidNode) {
hasValidNode = node.left != null || node.right != null;
}
} else {
list.add(null);
}
}

if (!hasValidNode) {
// while (!queue.isEmpty()) {
// queue.poll();
// }

break;
}
}

while (!list.isEmpty() && list.get(list.size() - 1) == null) {
list.remove(list.size() - 1);
}

return list.toArray(new Integer[0]);
}
}
}

class TestMain {

public static void main(String[] args) {
TestUtils.runTestCases(TestCase.class);
}

public static class TestCase {

public static boolean testCase1() {
Integer[] nums = { 5, 4, 8, 11, null, 13, 4, 7, 2, null, null, 5, 1 };
int sum = 22;

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<List<Integer>> result = new Solution().pathSum(tree, sum);
Integer[][] expect = { { 5, 4, 11, 2 }, { 5, 8, 4, 5 } };

return TestUtils.check(result, expect);
}

public static boolean testCase2() {
Integer[] nums = { 1, 2, 3 };
int sum = 5;

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<List<Integer>> result = new Solution().pathSum(tree, sum);
Integer[][] expect = {};

return TestUtils.check(result, expect);
}

public static boolean testCase3() {
Integer[] nums = { 1, 2 };
int sum = 0;

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<List<Integer>> result = new Solution().pathSum(tree, sum);
Integer[][] expect = {};

return TestUtils.check(result, expect);
}
}

public static class TestUtils {

public static boolean check(Object result, Object expect) {
result = normalizeObject(result);
expect = normalizeObject(expect);
boolean ok = java.util.Objects.deepEquals(result, expect);
printCheck(toString(result), toString(expect), ok);
return ok;
}

public static boolean check(Object result, String expect) {
boolean ok = java.util.Objects.equals(normalizeString(toString(result)),
normalizeString(toString(expect)));
printCheck(normalizeString(toString(result)), normalizeString(toString(expect)), ok);
return ok;
}

private static Object normalizeObject(Object o) {
if (o instanceof java.util.List) {
java.util.List<?> list = (java.util.List<?>) o;
if (list != null && !list.isEmpty() && list.get(0) instanceof java.util.List) {
o = toArrays(list);
} else {
o = toArray(list);
}
}

return o;
}

private static String toString(Object o) {
if (o instanceof Object[]) {
return java.util.Arrays.deepToString((Object[]) o);
} else if (o instanceof int[]) {
return java.util.Arrays.toString((int[]) o);
} else if (o instanceof double[]) {
return java.util.Arrays.toString((double[]) o);
} else if (o instanceof char[]) {
return java.util.Arrays.toString((char[]) o);
} else {
return java.util.Objects.toString(o);
}
}

private static String normalizeString(String s) {
boolean isArray = (s.startsWith("{") && s.endsWith("}")) || (s.startsWith("[") && s.endsWith("]"));
if (isArray) {
s = s.replace(" ", "")
.replace("'", "")
.replace("\"", "")
.replace("{", "[")
.replace("}", "]");
}

return s;
}

private static void printCheck(String result, String expect, boolean ok) {
// System.out.println();
// System.out.println("--->");

System.out.println("result: " + result);
System.out.println("expect: " + expect);

System.out.println();
if (ok) {
System.out.println("比较结果为: 正确(right)");
} else {
System.out.println("比较结果为: 错误(error)");
}

// System.out.println();
// System.out.println("<---");
}

public static void runTestCases(Class<?> clazz) {
java.lang.reflect.Method[] methods = clazz.getDeclaredMethods();
java.util.Arrays.sort(methods, (o1, o2) -> {
return o1.getName().compareTo(o2.getName());
});
for (java.lang.reflect.Method method : methods) {
if (method.getName().startsWith("test")) {
System.out.println(String.format("--- %s --->", method.getName()));

Object object = null;
try {
object = method.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println(String.format("<--- %s ---", method.getName()));

if (object instanceof Boolean) {
Boolean ok = (Boolean) object;
if (!ok) {
break;
}
} else {
throw new RuntimeException(String.format("测试用例方法%s的返回值需要为布尔类型", method.getName()));
}
}
}
}

public static Object[] toArray(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0];
}

return list.toArray();
}

public static Object[][] toArrays(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0][0];
}

Object[][] arrays = new Object[list.size()][];
for (int i = 0; i < list.size(); i++) {
arrays[i] = toArray(list.get(i));
}

return arrays;
}

@SuppressWarnings("unchecked")
public static <T> T[] genArray(Class<T> clazz, int length) {
return (T[]) java.lang.reflect.Array.newInstance(clazz, length);
}

@SuppressWarnings("unchecked")
public static <T> T[][] genArrays(Class<T> clazz, int rows, int cols) {
T[] array = genArray(clazz, 0);

T[][] arrays = (T[][]) genArray(array.getClass(), rows);
for (int i = 0; i < arrays.length; i++) {
arrays[i] = genArray(clazz, cols);
}

return arrays;
}

public static <T> T[] toArray(java.util.List<T> list, Class<T> clazz) {
if (list == null || list.isEmpty()) {
return genArray(clazz, 0);
}

T[] array = genArray(clazz, list.size());
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}

return array;
}

public static <T> T[][] toArrays(java.util.List<java.util.List<T>> lists, Class<T> clazz) {
if (lists == null || lists.isEmpty()) {
return genArrays(clazz, 0, 0);
}

T[][] arrays = genArrays(clazz, lists.size(), 0);
for (int i = 0; i < lists.size(); i++) {
arrays[i] = toArray(lists.get(i), clazz);
}

return arrays;
}

public static <T> java.util.List<T> toList(T[] array) {
return java.util.Arrays.asList(array);
}

public static <T> java.util.List<java.util.List<T>> toLists(T[][] arrays) {
java.util.List<java.util.List<T>> lists = new java.util.ArrayList<>();
for (T[] array : arrays) {
lists.add(toList(array));
}

return lists;
}
}
}

路径总和III

题目描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
给定一个二叉树的根节点 root ,和一个整数 targetSum ,求该二叉树里节点值之和等于 targetSum 的 路径 的数目。

路径 不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。



示例 1:

输入:root = [10,5,-3,3,2,null,11,3,-2,null,1], targetSum = 8
输出:3
解释:和等于 8 的路径有 3 条,如图所示。
示例 2:

输入:root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22
输出:3


提示:

二叉树的节点个数的范围是 [0,1000]
-109 <= Node.val <= 109
-1000 <= targetSum <= 1000

题目解答

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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
public class Solution {
public int pathSum(TreeNode root, int targetSum) {
if (root == null) {
return 0;
}

int count = nodeSum(root, targetSum);
count += pathSum(root.left, targetSum);
count += pathSum(root.right, targetSum);
return count;
}

public int nodeSum(TreeNode root, int targetSum) {
if (root == null) {
return 0;
}

int count = 0;

int val = root.val;
if (val == targetSum) {
count++;
}

count += nodeSum(root.left, targetSum - val);
count += nodeSum(root.right, targetSum - val);

return count;
}

static class TreeNode {
int val;
TreeNode left;
TreeNode right;

TreeNode() {
}

TreeNode(int val) {
this.val = val;
}

TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}

public static TreeNode genTree(Integer[] array) {
if (array.length == 0) {
return null;
}

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
TreeNode root = new TreeNode(array[0]);
queue.offer(root);

Integer v = null;
int i = 1;
while (i < array.length) {
TreeNode node = queue.poll();

TreeNode left = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;
TreeNode right = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;

// 数组中不包含空节点的子节点的写法(不标准的完全二叉树含空节点的层次遍历)
node.left = left;
node.right = right;
if (left != null) {
queue.offer(left);
}
if (right != null) {
queue.offer(right);
}

// 数组中包含空节点的子节点的写法(标准的完全二叉树含空节点的层次遍历)
// if (node != null) {
// node.left = left;
// node.right = right;
// }
// queue.offer(left);
// queue.offer(right);
}

return root;
}

public static Integer[] toArray(TreeNode root) {
if (root == null) {
return new Integer[0];
}

java.util.LinkedList<Integer> list = new java.util.LinkedList<>();

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
boolean hasValidNode = false;

int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();

if (node != null) {
list.add(node.val);

queue.offer(node.left);
queue.offer(node.right);

if (!hasValidNode) {
hasValidNode = node.left != null || node.right != null;
}
} else {
list.add(null);
}
}

if (!hasValidNode) {
// while (!queue.isEmpty()) {
// queue.poll();
// }

break;
}
}

while (!list.isEmpty() && list.get(list.size() - 1) == null) {
list.remove(list.size() - 1);
}

return list.toArray(new Integer[0]);
}
}
}

class TestMain {

public static void main(String[] args) {
TestUtils.runTestCases(TestCase.class);
}

public static class TestCase {

public static boolean testCase1() {
Integer[] nums = { 10, 5, -3, 3, 2, null, 11, 3, -2, null, 1 };
int sum = 8;

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
int result = new Solution().pathSum(tree, sum);
int expect = 3;

return TestUtils.check(result, expect);
}

public static boolean testCase2() {
Integer[] nums = { 5, 4, 8, 11, null, 13, 4, 7, 2, null, null, 5, 1 };
int sum = 22;

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
int result = new Solution().pathSum(tree, sum);
int expect = 3;

return TestUtils.check(result, expect);
}

public static boolean testCase3() {
Integer[] nums = { 0, 1, 1 };
int sum = 1;

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
int result = new Solution().pathSum(tree, sum);
int expect = 4;

return TestUtils.check(result, expect);
}
}

public static class TestUtils {

public static boolean check(Object result, Object expect) {
result = normalizeObject(result);
expect = normalizeObject(expect);
boolean ok = java.util.Objects.deepEquals(result, expect);
printCheck(toString(result), toString(expect), ok);
return ok;
}

public static boolean check(Object result, String expect) {
boolean ok = java.util.Objects.equals(normalizeString(toString(result)),
normalizeString(toString(expect)));
printCheck(normalizeString(toString(result)), normalizeString(toString(expect)), ok);
return ok;
}

private static Object normalizeObject(Object o) {
if (o instanceof java.util.List) {
java.util.List<?> list = (java.util.List<?>) o;
if (list != null && !list.isEmpty() && list.get(0) instanceof java.util.List) {
o = toArrays(list);
} else {
o = toArray(list);
}
}

return o;
}

private static String toString(Object o) {
if (o instanceof Object[]) {
return java.util.Arrays.deepToString((Object[]) o);
} else if (o instanceof int[]) {
return java.util.Arrays.toString((int[]) o);
} else if (o instanceof double[]) {
return java.util.Arrays.toString((double[]) o);
} else if (o instanceof char[]) {
return java.util.Arrays.toString((char[]) o);
} else {
return java.util.Objects.toString(o);
}
}

private static String normalizeString(String s) {
boolean isArray = (s.startsWith("{") && s.endsWith("}")) || (s.startsWith("[") && s.endsWith("]"));
if (isArray) {
s = s.replace(" ", "")
.replace("'", "")
.replace("\"", "")
.replace("{", "[")
.replace("}", "]");
}

return s;
}

private static void printCheck(String result, String expect, boolean ok) {
// System.out.println();
// System.out.println("--->");

System.out.println("result: " + result);
System.out.println("expect: " + expect);

System.out.println();
if (ok) {
System.out.println("比较结果为: 正确(right)");
} else {
System.out.println("比较结果为: 错误(error)");
}

// System.out.println();
// System.out.println("<---");
}

public static void runTestCases(Class<?> clazz) {
java.lang.reflect.Method[] methods = clazz.getDeclaredMethods();
java.util.Arrays.sort(methods, (o1, o2) -> {
return o1.getName().compareTo(o2.getName());
});
for (java.lang.reflect.Method method : methods) {
if (method.getName().startsWith("test")) {
System.out.println(String.format("--- %s --->", method.getName()));

Object object = null;
try {
object = method.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println(String.format("<--- %s ---", method.getName()));

if (object instanceof Boolean) {
Boolean ok = (Boolean) object;
if (!ok) {
break;
}
} else {
throw new RuntimeException(String.format("测试用例方法%s的返回值需要为布尔类型", method.getName()));
}
}
}
}

public static Object[] toArray(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0];
}

return list.toArray();
}

public static Object[][] toArrays(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0][0];
}

Object[][] arrays = new Object[list.size()][];
for (int i = 0; i < list.size(); i++) {
arrays[i] = toArray(list.get(i));
}

return arrays;
}

@SuppressWarnings("unchecked")
public static <T> T[] genArray(Class<T> clazz, int length) {
return (T[]) java.lang.reflect.Array.newInstance(clazz, length);
}

@SuppressWarnings("unchecked")
public static <T> T[][] genArrays(Class<T> clazz, int rows, int cols) {
T[] array = genArray(clazz, 0);

T[][] arrays = (T[][]) genArray(array.getClass(), rows);
for (int i = 0; i < arrays.length; i++) {
arrays[i] = genArray(clazz, cols);
}

return arrays;
}

public static <T> T[] toArray(java.util.List<T> list, Class<T> clazz) {
if (list == null || list.isEmpty()) {
return genArray(clazz, 0);
}

T[] array = genArray(clazz, list.size());
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}

return array;
}

public static <T> T[][] toArrays(java.util.List<java.util.List<T>> lists, Class<T> clazz) {
if (lists == null || lists.isEmpty()) {
return genArrays(clazz, 0, 0);
}

T[][] arrays = genArrays(clazz, lists.size(), 0);
for (int i = 0; i < lists.size(); i++) {
arrays[i] = toArray(lists.get(i), clazz);
}

return arrays;
}

public static <T> java.util.List<T> toList(T[] array) {
return java.util.Arrays.asList(array);
}

public static <T> java.util.List<java.util.List<T>> toLists(T[][] arrays) {
java.util.List<java.util.List<T>> lists = new java.util.ArrayList<>();
for (T[] array : arrays) {
lists.add(toList(array));
}

return lists;
}
}
}

进阶解法

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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

public class Solution {
private int count = 0;
private Map<TreeNode, Map<TreeNode, String>> paths = new HashMap<>();
private Map<TreeNode, TreeNode> map = new HashMap<>(); // 存储每个结点到双亲结点的映射

public int pathSum(TreeNode root, int targetSum) {
if (root == null) {
return count;
}

if (root.left == null && root.right == null) {
List<TreeNode> list = new LinkedList<>();

TreeNode p = root;
while (p != null) {
list.add(0, p);

p = map.get(p);
}

for (int i = 0; i < list.size(); i++) {
int sum = 0;
for (int j = i; j < list.size(); j++) {
sum = sum + list.get(j).val;
if (sum == targetSum) {
// List<String> tmp = new LinkedList<>();
// for (int k = i; k <= j; k++) {
// TreeNode node = list.get(k);

// tmp.add(node.val + "");
// // tmp.add(node.val + "@" + node);
// }

// String path = String.join("->", tmp);

// // System.out.println(list);
// // System.out.println(path);

TreeNode x = list.get(i);
TreeNode y = list.get(j);

Map<TreeNode, String> nodes = paths.computeIfAbsent(x, k -> new HashMap<>());
if (nodes.containsKey(y)) {
continue;
} else {
// paths.put(y, path);
nodes.put(y, null);
count++;
}
}
}
}
}

map.put(root.left, root);
map.put(root.right, root);

pathSum(root.left, targetSum);
pathSum(root.right, targetSum);

return count;
}

static class TreeNode {
int val;
TreeNode left;
TreeNode right;

TreeNode() {
}

TreeNode(int val) {
this.val = val;
}

TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}

public static TreeNode genTree(Integer[] array) {
if (array.length == 0) {
return null;
}

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
TreeNode root = new TreeNode(array[0]);
queue.offer(root);

Integer v = null;
int i = 1;
while (i < array.length) {
TreeNode node = queue.poll();

TreeNode left = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;
TreeNode right = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;

// 数组中不包含空节点的子节点的写法(不标准的完全二叉树含空节点的层次遍历)
node.left = left;
node.right = right;
if (left != null) {
queue.offer(left);
}
if (right != null) {
queue.offer(right);
}

// 数组中包含空节点的子节点的写法(标准的完全二叉树含空节点的层次遍历)
// if (node != null) {
// node.left = left;
// node.right = right;
// }
// queue.offer(left);
// queue.offer(right);
}

return root;
}

public static Integer[] toArray(TreeNode root) {
if (root == null) {
return new Integer[0];
}

java.util.LinkedList<Integer> list = new java.util.LinkedList<>();

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
boolean hasValidNode = false;

int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();

if (node != null) {
list.add(node.val);

queue.offer(node.left);
queue.offer(node.right);

if (!hasValidNode) {
hasValidNode = node.left != null || node.right != null;
}
} else {
list.add(null);
}
}

if (!hasValidNode) {
// while (!queue.isEmpty()) {
// queue.poll();
// }

break;
}
}

while (!list.isEmpty() && list.get(list.size() - 1) == null) {
list.remove(list.size() - 1);
}

return list.toArray(new Integer[0]);
}
}
}

class TestMain {

public static void main(String[] args) {
TestUtils.runTestCases(TestCase.class);
}

public static class TestCase {

public static boolean testCase1() {
Integer[] nums = { 10, 5, -3, 3, 2, null, 11, 3, -2, null, 1 };
int sum = 8;

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
int result = new Solution().pathSum(tree, sum);
int expect = 3;

return TestUtils.check(result, expect);
}

public static boolean testCase2() {
Integer[] nums = { 5, 4, 8, 11, null, 13, 4, 7, 2, null, null, 5, 1 };
int sum = 22;

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
int result = new Solution().pathSum(tree, sum);
int expect = 3;

return TestUtils.check(result, expect);
}

public static boolean testCase3() {
Integer[] nums = { 0, 1, 1 };
int sum = 1;

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
int result = new Solution().pathSum(tree, sum);
int expect = 4;

return TestUtils.check(result, expect);
}
}

public static class TestUtils {

public static boolean check(Object result, Object expect) {
result = normalizeObject(result);
expect = normalizeObject(expect);
boolean ok = java.util.Objects.deepEquals(result, expect);
printCheck(toString(result), toString(expect), ok);
return ok;
}

public static boolean check(Object result, String expect) {
boolean ok = java.util.Objects.equals(normalizeString(toString(result)),
normalizeString(toString(expect)));
printCheck(normalizeString(toString(result)), normalizeString(toString(expect)), ok);
return ok;
}

private static Object normalizeObject(Object o) {
if (o instanceof java.util.List) {
java.util.List<?> list = (java.util.List<?>) o;
if (list != null && !list.isEmpty() && list.get(0) instanceof java.util.List) {
o = toArrays(list);
} else {
o = toArray(list);
}
}

return o;
}

private static String toString(Object o) {
if (o instanceof Object[]) {
return java.util.Arrays.deepToString((Object[]) o);
} else if (o instanceof int[]) {
return java.util.Arrays.toString((int[]) o);
} else if (o instanceof double[]) {
return java.util.Arrays.toString((double[]) o);
} else if (o instanceof char[]) {
return java.util.Arrays.toString((char[]) o);
} else {
return java.util.Objects.toString(o);
}
}

private static String normalizeString(String s) {
boolean isArray = (s.startsWith("{") && s.endsWith("}")) || (s.startsWith("[") && s.endsWith("]"));
if (isArray) {
s = s.replace(" ", "")
.replace("'", "")
.replace("\"", "")
.replace("{", "[")
.replace("}", "]");
}

return s;
}

private static void printCheck(String result, String expect, boolean ok) {
// System.out.println();
// System.out.println("--->");

System.out.println("result: " + result);
System.out.println("expect: " + expect);

System.out.println();
if (ok) {
System.out.println("比较结果为: 正确(right)");
} else {
System.out.println("比较结果为: 错误(error)");
}

// System.out.println();
// System.out.println("<---");
}

public static void runTestCases(Class<?> clazz) {
java.lang.reflect.Method[] methods = clazz.getDeclaredMethods();
java.util.Arrays.sort(methods, (o1, o2) -> {
return o1.getName().compareTo(o2.getName());
});
for (java.lang.reflect.Method method : methods) {
if (method.getName().startsWith("test")) {
System.out.println(String.format("--- %s --->", method.getName()));

Object object = null;
try {
object = method.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println(String.format("<--- %s ---", method.getName()));

if (object instanceof Boolean) {
Boolean ok = (Boolean) object;
if (!ok) {
break;
}
} else {
throw new RuntimeException(String.format("测试用例方法%s的返回值需要为布尔类型", method.getName()));
}
}
}
}

public static Object[] toArray(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0];
}

return list.toArray();
}

public static Object[][] toArrays(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0][0];
}

Object[][] arrays = new Object[list.size()][];
for (int i = 0; i < list.size(); i++) {
arrays[i] = toArray(list.get(i));
}

return arrays;
}

@SuppressWarnings("unchecked")
public static <T> T[] genArray(Class<T> clazz, int length) {
return (T[]) java.lang.reflect.Array.newInstance(clazz, length);
}

@SuppressWarnings("unchecked")
public static <T> T[][] genArrays(Class<T> clazz, int rows, int cols) {
T[] array = genArray(clazz, 0);

T[][] arrays = (T[][]) genArray(array.getClass(), rows);
for (int i = 0; i < arrays.length; i++) {
arrays[i] = genArray(clazz, cols);
}

return arrays;
}

public static <T> T[] toArray(java.util.List<T> list, Class<T> clazz) {
if (list == null || list.isEmpty()) {
return genArray(clazz, 0);
}

T[] array = genArray(clazz, list.size());
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}

return array;
}

public static <T> T[][] toArrays(java.util.List<java.util.List<T>> lists, Class<T> clazz) {
if (lists == null || lists.isEmpty()) {
return genArrays(clazz, 0, 0);
}

T[][] arrays = genArrays(clazz, lists.size(), 0);
for (int i = 0; i < lists.size(); i++) {
arrays[i] = toArray(lists.get(i), clazz);
}

return arrays;
}

public static <T> java.util.List<T> toList(T[] array) {
return java.util.Arrays.asList(array);
}

public static <T> java.util.List<java.util.List<T>> toLists(T[][] arrays) {
java.util.List<java.util.List<T>> lists = new java.util.ArrayList<>();
for (T[] array : arrays) {
lists.add(toList(array));
}

return lists;
}
}
}

其他解法

解法1

前缀和

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Solution {
public int pathSum(TreeNode root, int targetSum) {
Map<Long, Integer> prefix = new HashMap<Long, Integer>();
prefix.put(0L, 1);
return dfs(root, prefix, 0, targetSum);
}

public int dfs(TreeNode root, Map<Long, Integer> prefix, long curr, int targetSum) {
if (root == null) {
return 0;
}

int ret = 0;
curr += root.val;

ret = prefix.getOrDefault(curr - targetSum, 0);
prefix.put(curr, prefix.getOrDefault(curr, 0) + 1);
ret += dfs(root.left, prefix, curr, targetSum);
ret += dfs(root.right, prefix, curr, targetSum);
prefix.put(curr, prefix.getOrDefault(curr, 0) - 1);

return ret;
}
}

求根节点到叶节点数字之和

题目描述

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
给你一个二叉树的根节点 root ,树中每个节点都存放有一个 0 到 9 之间的数字。
每条从根节点到叶节点的路径都代表一个数字:

例如,从根节点到叶节点的路径 1 -> 2 -> 3 表示数字 123 。
计算从根节点到叶节点生成的 所有数字之和 。

叶节点 是指没有子节点的节点。



示例 1:

输入:root = [1,2,3]
输出:25
解释:
从根到叶子节点路径 1->2 代表数字 12
从根到叶子节点路径 1->3 代表数字 13
因此,数字总和 = 12 + 13 = 25
示例 2:

输入:root = [4,9,0,5,1]
输出:1026
解释:
从根到叶子节点路径 4->9->5 代表数字 495
从根到叶子节点路径 4->9->1 代表数字 491
从根到叶子节点路径 4->0 代表数字 40
因此,数字总和 = 495 + 491 + 40 = 1026


提示:

树中节点的数目在范围 [1, 1000] 内
0 <= Node.val <= 9
树的深度不超过 10

题目解答

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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
public class Solution {
private int totalSum = 0;

public int sumNumbers(TreeNode root) {
sumNumbers(root, 0);

return totalSum;
}

private void sumNumbers(TreeNode node, int parentSum) {
if (node == null) {
return;
}

int nodeSum = parentSum * 10 + node.val;

if (node.left == null && node.right == null) {
totalSum = totalSum + nodeSum;
}

sumNumbers(node.left, nodeSum);
sumNumbers(node.right, nodeSum);
}

static class TreeNode {
int val;
TreeNode left;
TreeNode right;

TreeNode() {
}

TreeNode(int val) {
this.val = val;
}

TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}

public static TreeNode genTree(Integer[] array) {
if (array.length == 0) {
return null;
}

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
TreeNode root = new TreeNode(array[0]);
queue.offer(root);

Integer v = null;
int i = 1;
while (i < array.length) {
TreeNode node = queue.poll();

TreeNode left = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;
TreeNode right = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;

// 数组中不包含空节点的子节点的写法(不标准的完全二叉树含空节点的层次遍历)
node.left = left;
node.right = right;
if (left != null) {
queue.offer(left);
}
if (right != null) {
queue.offer(right);
}

// 数组中包含空节点的子节点的写法(标准的完全二叉树含空节点的层次遍历)
// if (node != null) {
// node.left = left;
// node.right = right;
// }
// queue.offer(left);
// queue.offer(right);
}

return root;
}

public static Integer[] toArray(TreeNode root) {
if (root == null) {
return new Integer[0];
}

java.util.LinkedList<Integer> list = new java.util.LinkedList<>();

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
boolean hasValidNode = false;

int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();

if (node != null) {
list.add(node.val);

queue.offer(node.left);
queue.offer(node.right);

if (!hasValidNode) {
hasValidNode = node.left != null || node.right != null;
}
} else {
list.add(null);
}
}

if (!hasValidNode) {
// while (!queue.isEmpty()) {
// queue.poll();
// }

break;
}
}

while (!list.isEmpty() && list.get(list.size() - 1) == null) {
list.remove(list.size() - 1);
}

return list.toArray(new Integer[0]);
}
}
}

class TestMain {

public static void main(String[] args) {
TestUtils.runTestCases(TestCase.class);
}

public static class TestCase {

public static boolean testCase1() {
Integer[] nums = { 1, 2, 3 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
int result = new Solution().sumNumbers(tree);
int expect = 25;

return TestUtils.check(result, expect);
}

public static boolean testCase2() {
Integer[] nums = { 4, 9, 0, 5, 1 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
int result = new Solution().sumNumbers(tree);
int expect = 1026;

return TestUtils.check(result, expect);
}

public static boolean testCase3() {
Integer[] nums = { 1, 0 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
int result = new Solution().sumNumbers(tree);
int expect = 10;

return TestUtils.check(result, expect);
}
}

public static class TestUtils {

public static boolean check(Object result, Object expect) {
result = normalizeObject(result);
expect = normalizeObject(expect);
boolean ok = java.util.Objects.deepEquals(result, expect);
printCheck(toString(result), toString(expect), ok);
return ok;
}

public static boolean check(Object result, String expect) {
boolean ok = java.util.Objects.equals(normalizeString(toString(result)),
normalizeString(toString(expect)));
printCheck(normalizeString(toString(result)), normalizeString(toString(expect)), ok);
return ok;
}

private static Object normalizeObject(Object o) {
if (o instanceof java.util.List) {
java.util.List<?> list = (java.util.List<?>) o;
if (list != null && !list.isEmpty() && list.get(0) instanceof java.util.List) {
o = toArrays(list);
} else {
o = toArray(list);
}
}

return o;
}

private static String toString(Object o) {
if (o instanceof Object[]) {
return java.util.Arrays.deepToString((Object[]) o);
} else if (o instanceof int[]) {
return java.util.Arrays.toString((int[]) o);
} else if (o instanceof double[]) {
return java.util.Arrays.toString((double[]) o);
} else if (o instanceof char[]) {
return java.util.Arrays.toString((char[]) o);
} else {
return java.util.Objects.toString(o);
}
}

private static String normalizeString(String s) {
boolean isArray = (s.startsWith("{") && s.endsWith("}")) || (s.startsWith("[") && s.endsWith("]"));
if (isArray) {
s = s.replace(" ", "")
.replace("'", "")
.replace("\"", "")
.replace("{", "[")
.replace("}", "]");
}

return s;
}

private static void printCheck(String result, String expect, boolean ok) {
// System.out.println();
// System.out.println("--->");

System.out.println("result: " + result);
System.out.println("expect: " + expect);

System.out.println();
if (ok) {
System.out.println("比较结果为: 正确(right)");
} else {
System.out.println("比较结果为: 错误(error)");
}

// System.out.println();
// System.out.println("<---");
}

public static void runTestCases(Class<?> clazz) {
java.lang.reflect.Method[] methods = clazz.getDeclaredMethods();
java.util.Arrays.sort(methods, (o1, o2) -> {
return o1.getName().compareTo(o2.getName());
});
for (java.lang.reflect.Method method : methods) {
if (method.getName().startsWith("test")) {
System.out.println(String.format("--- %s --->", method.getName()));

Object object = null;
try {
object = method.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println(String.format("<--- %s ---", method.getName()));

if (object instanceof Boolean) {
Boolean ok = (Boolean) object;
if (!ok) {
break;
}
} else {
throw new RuntimeException(String.format("测试用例方法%s的返回值需要为布尔类型", method.getName()));
}
}
}
}

public static Object[] toArray(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0];
}

return list.toArray();
}

public static Object[][] toArrays(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0][0];
}

Object[][] arrays = new Object[list.size()][];
for (int i = 0; i < list.size(); i++) {
arrays[i] = toArray(list.get(i));
}

return arrays;
}

@SuppressWarnings("unchecked")
public static <T> T[] genArray(Class<T> clazz, int length) {
return (T[]) java.lang.reflect.Array.newInstance(clazz, length);
}

@SuppressWarnings("unchecked")
public static <T> T[][] genArrays(Class<T> clazz, int rows, int cols) {
T[] array = genArray(clazz, 0);

T[][] arrays = (T[][]) genArray(array.getClass(), rows);
for (int i = 0; i < arrays.length; i++) {
arrays[i] = genArray(clazz, cols);
}

return arrays;
}

public static <T> T[] toArray(java.util.List<T> list, Class<T> clazz) {
if (list == null || list.isEmpty()) {
return genArray(clazz, 0);
}

T[] array = genArray(clazz, list.size());
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}

return array;
}

public static <T> T[][] toArrays(java.util.List<java.util.List<T>> lists, Class<T> clazz) {
if (lists == null || lists.isEmpty()) {
return genArrays(clazz, 0, 0);
}

T[][] arrays = genArrays(clazz, lists.size(), 0);
for (int i = 0; i < lists.size(); i++) {
arrays[i] = toArray(lists.get(i), clazz);
}

return arrays;
}

public static <T> java.util.List<T> toList(T[] array) {
return java.util.Arrays.asList(array);
}

public static <T> java.util.List<java.util.List<T>> toLists(T[][] arrays) {
java.util.List<java.util.List<T>> lists = new java.util.ArrayList<>();
for (T[] array : arrays) {
lists.add(toList(array));
}

return lists;
}
}
}

进阶解法

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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

public class Solution {
private int totalSum = 0;
private Map<TreeNode, TreeNode> map = new HashMap<>(); // 存储每个结点到双亲结点的映射

public int sumNumbers(TreeNode root) {
if (root == null) {
return 0;
}

if (root.left == null && root.right == null) {
List<Integer> list = new LinkedList<>();

TreeNode p = root;
while (p != null) {
list.add(0, p.val);

p = map.get(p);
}

int sum = 0;
for (int i = 0; i < list.size(); i++) {
sum = 10 * sum + list.get(i);
}

totalSum = totalSum + sum;
}

map.put(root.left, root);
map.put(root.right, root);

sumNumbers(root.left);
sumNumbers(root.right);

return totalSum;
}

static class TreeNode {
int val;
TreeNode left;
TreeNode right;

TreeNode() {
}

TreeNode(int val) {
this.val = val;
}

TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}

public static TreeNode genTree(Integer[] array) {
if (array.length == 0) {
return null;
}

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
TreeNode root = new TreeNode(array[0]);
queue.offer(root);

Integer v = null;
int i = 1;
while (i < array.length) {
TreeNode node = queue.poll();

TreeNode left = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;
TreeNode right = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;

// 数组中不包含空节点的子节点的写法(不标准的完全二叉树含空节点的层次遍历)
node.left = left;
node.right = right;
if (left != null) {
queue.offer(left);
}
if (right != null) {
queue.offer(right);
}

// 数组中包含空节点的子节点的写法(标准的完全二叉树含空节点的层次遍历)
// if (node != null) {
// node.left = left;
// node.right = right;
// }
// queue.offer(left);
// queue.offer(right);
}

return root;
}

public static Integer[] toArray(TreeNode root) {
if (root == null) {
return new Integer[0];
}

java.util.LinkedList<Integer> list = new java.util.LinkedList<>();

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
boolean hasValidNode = false;

int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();

if (node != null) {
list.add(node.val);

queue.offer(node.left);
queue.offer(node.right);

if (!hasValidNode) {
hasValidNode = node.left != null || node.right != null;
}
} else {
list.add(null);
}
}

if (!hasValidNode) {
// while (!queue.isEmpty()) {
// queue.poll();
// }

break;
}
}

while (!list.isEmpty() && list.get(list.size() - 1) == null) {
list.remove(list.size() - 1);
}

return list.toArray(new Integer[0]);
}
}
}

class TestMain {

public static void main(String[] args) {
TestUtils.runTestCases(TestCase.class);
}

public static class TestCase {

public static boolean testCase1() {
Integer[] nums = { 1, 2, 3 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
int result = new Solution().sumNumbers(tree);
int expect = 25;

return TestUtils.check(result, expect);
}

public static boolean testCase2() {
Integer[] nums = { 4, 9, 0, 5, 1 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
int result = new Solution().sumNumbers(tree);
int expect = 1026;

return TestUtils.check(result, expect);
}

public static boolean testCase3() {
Integer[] nums = { 1, 0 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
int result = new Solution().sumNumbers(tree);
int expect = 10;

return TestUtils.check(result, expect);
}
}

public static class TestUtils {

public static boolean check(Object result, Object expect) {
result = normalizeObject(result);
expect = normalizeObject(expect);
boolean ok = java.util.Objects.deepEquals(result, expect);
printCheck(toString(result), toString(expect), ok);
return ok;
}

public static boolean check(Object result, String expect) {
boolean ok = java.util.Objects.equals(normalizeString(toString(result)),
normalizeString(toString(expect)));
printCheck(normalizeString(toString(result)), normalizeString(toString(expect)), ok);
return ok;
}

private static Object normalizeObject(Object o) {
if (o instanceof java.util.List) {
java.util.List<?> list = (java.util.List<?>) o;
if (list != null && !list.isEmpty() && list.get(0) instanceof java.util.List) {
o = toArrays(list);
} else {
o = toArray(list);
}
}

return o;
}

private static String toString(Object o) {
if (o instanceof Object[]) {
return java.util.Arrays.deepToString((Object[]) o);
} else if (o instanceof int[]) {
return java.util.Arrays.toString((int[]) o);
} else if (o instanceof double[]) {
return java.util.Arrays.toString((double[]) o);
} else if (o instanceof char[]) {
return java.util.Arrays.toString((char[]) o);
} else {
return java.util.Objects.toString(o);
}
}

private static String normalizeString(String s) {
boolean isArray = (s.startsWith("{") && s.endsWith("}")) || (s.startsWith("[") && s.endsWith("]"));
if (isArray) {
s = s.replace(" ", "")
.replace("'", "")
.replace("\"", "")
.replace("{", "[")
.replace("}", "]");
}

return s;
}

private static void printCheck(String result, String expect, boolean ok) {
// System.out.println();
// System.out.println("--->");

System.out.println("result: " + result);
System.out.println("expect: " + expect);

System.out.println();
if (ok) {
System.out.println("比较结果为: 正确(right)");
} else {
System.out.println("比较结果为: 错误(error)");
}

// System.out.println();
// System.out.println("<---");
}

public static void runTestCases(Class<?> clazz) {
java.lang.reflect.Method[] methods = clazz.getDeclaredMethods();
java.util.Arrays.sort(methods, (o1, o2) -> {
return o1.getName().compareTo(o2.getName());
});
for (java.lang.reflect.Method method : methods) {
if (method.getName().startsWith("test")) {
System.out.println(String.format("--- %s --->", method.getName()));

Object object = null;
try {
object = method.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println(String.format("<--- %s ---", method.getName()));

if (object instanceof Boolean) {
Boolean ok = (Boolean) object;
if (!ok) {
break;
}
} else {
throw new RuntimeException(String.format("测试用例方法%s的返回值需要为布尔类型", method.getName()));
}
}
}
}

public static Object[] toArray(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0];
}

return list.toArray();
}

public static Object[][] toArrays(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0][0];
}

Object[][] arrays = new Object[list.size()][];
for (int i = 0; i < list.size(); i++) {
arrays[i] = toArray(list.get(i));
}

return arrays;
}

@SuppressWarnings("unchecked")
public static <T> T[] genArray(Class<T> clazz, int length) {
return (T[]) java.lang.reflect.Array.newInstance(clazz, length);
}

@SuppressWarnings("unchecked")
public static <T> T[][] genArrays(Class<T> clazz, int rows, int cols) {
T[] array = genArray(clazz, 0);

T[][] arrays = (T[][]) genArray(array.getClass(), rows);
for (int i = 0; i < arrays.length; i++) {
arrays[i] = genArray(clazz, cols);
}

return arrays;
}

public static <T> T[] toArray(java.util.List<T> list, Class<T> clazz) {
if (list == null || list.isEmpty()) {
return genArray(clazz, 0);
}

T[] array = genArray(clazz, list.size());
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}

return array;
}

public static <T> T[][] toArrays(java.util.List<java.util.List<T>> lists, Class<T> clazz) {
if (lists == null || lists.isEmpty()) {
return genArrays(clazz, 0, 0);
}

T[][] arrays = genArrays(clazz, lists.size(), 0);
for (int i = 0; i < lists.size(); i++) {
arrays[i] = toArray(lists.get(i), clazz);
}

return arrays;
}

public static <T> java.util.List<T> toList(T[] array) {
return java.util.Arrays.asList(array);
}

public static <T> java.util.List<java.util.List<T>> toLists(T[][] arrays) {
java.util.List<java.util.List<T>> lists = new java.util.ArrayList<>();
for (T[] array : arrays) {
lists.add(toList(array));
}

return lists;
}
}
}

二叉搜索树迭代器

题目描述

1
2
3
4
5
6
7
实现一个二叉搜索树迭代器类BSTIterator ,表示一个按中序遍历二叉搜索树(BST)的迭代器:
BSTIterator(TreeNode root) 初始化 BSTIterator 类的一个对象。BST 的根节点 root 会作为构造函数的一部分给出。指针应初始化为一个不存在于 BST 中的数字,且该数字小于 BST 中的任何元素。
boolean hasNext() 如果向指针右侧遍历存在数字,则返回 true ;否则返回 false 。
int next()将指针向右移动,然后返回指针处的数字。
注意,指针初始化为一个不存在于 BST 中的数字,所以对 next() 的首次调用将返回 BST 中的最小元素。

你可以假设 next() 调用总是有效的,也就是说,当调用 next() 时,BST 的中序遍历中至少存在一个下一个数字。

题目解答

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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
import java.util.Deque;
import java.util.LinkedList;

class BSTIterator {
private Deque<TreeNode> stack = new LinkedList<>();
private TreeNode p;

public BSTIterator(TreeNode root) {
p = root;
}

public int next() {
TreeNode node = null;

while (p != null || !stack.isEmpty()) {
if (p != null) {
stack.push(p);

p = p.left;
} else {
p = stack.pop();

node = p;

p = p.right;

// 得到一个元素后就退出(惰性迭代器)
break;
}
}

return node == null ? -1 : node.val;
}

public boolean hasNext() {
return p != null || !stack.isEmpty();
}

static class TreeNode {
int val;
TreeNode left;
TreeNode right;

TreeNode() {
}

TreeNode(int val) {
this.val = val;
}

TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}

public static TreeNode genTree(Integer[] array) {
if (array.length == 0) {
return null;
}

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
TreeNode root = new TreeNode(array[0]);
queue.offer(root);

Integer v = null;
int i = 1;
while (i < array.length) {
TreeNode node = queue.poll();

TreeNode left = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;
TreeNode right = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;

// 数组中不包含空节点的子节点的写法(不标准的完全二叉树含空节点的层次遍历)
node.left = left;
node.right = right;
if (left != null) {
queue.offer(left);
}
if (right != null) {
queue.offer(right);
}

// 数组中包含空节点的子节点的写法(标准的完全二叉树含空节点的层次遍历)
// if (node != null) {
// node.left = left;
// node.right = right;
// }
// queue.offer(left);
// queue.offer(right);
}

return root;
}

public static Integer[] toArray(TreeNode root) {
if (root == null) {
return new Integer[0];
}

java.util.LinkedList<Integer> list = new java.util.LinkedList<>();

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
boolean hasValidNode = false;

int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();

if (node != null) {
list.add(node.val);

queue.offer(node.left);
queue.offer(node.right);

if (!hasValidNode) {
hasValidNode = node.left != null || node.right != null;
}
} else {
list.add(null);
}
}

if (!hasValidNode) {
// while (!queue.isEmpty()) {
// queue.poll();
// }

break;
}
}

while (!list.isEmpty() && list.get(list.size() - 1) == null) {
list.remove(list.size() - 1);
}

return list.toArray(new Integer[0]);
}
}
}

class TestMain {

public static void main(String[] args) {
TestUtils.runTestCases(TestCase.class);
}

public static class TestCase {

public static boolean testCase1() {
Integer[] nums = { 7, 3, 15, null, null, 9, 20 };
String[] ops = { "BSTIterator", "next", "next", "hasNext", "next", "hasNext", "next", "hasNext", "next",
"hasNext" };

BSTIterator.TreeNode tree = BSTIterator.TreeNode.genTree(nums);
java.util.List<String> result = new LinkedList<>();
BSTIterator bst = null;
for (String op : ops) {
if (op.equals("BSTIterator")) {
bst = new BSTIterator(tree);
result.add("null");
} else if (op.equals("hasNext")) {
result.add("" + bst.hasNext());
} else if (op.equals("next")) {
result.add("" + bst.next());
}
}
String expect = "[null, 3, 7, true, 9, true, 15, true, 20, false]";

return TestUtils.check(result, expect);
}
}

public static class TestUtils {

public static boolean check(Object result, Object expect) {
result = normalizeObject(result);
expect = normalizeObject(expect);
boolean ok = java.util.Objects.deepEquals(result, expect);
printCheck(toString(result), toString(expect), ok);
return ok;
}

public static boolean check(Object result, String expect) {
boolean ok = java.util.Objects.equals(normalizeString(toString(result)),
normalizeString(toString(expect)));
printCheck(normalizeString(toString(result)), normalizeString(toString(expect)), ok);
return ok;
}

private static Object normalizeObject(Object o) {
if (o instanceof java.util.List) {
java.util.List<?> list = (java.util.List<?>) o;
if (list != null && !list.isEmpty() && list.get(0) instanceof java.util.List) {
o = toArrays(list);
} else {
o = toArray(list);
}
}

return o;
}

private static String toString(Object o) {
if (o instanceof Object[]) {
return java.util.Arrays.deepToString((Object[]) o);
} else if (o instanceof int[]) {
return java.util.Arrays.toString((int[]) o);
} else if (o instanceof double[]) {
return java.util.Arrays.toString((double[]) o);
} else if (o instanceof char[]) {
return java.util.Arrays.toString((char[]) o);
} else {
return java.util.Objects.toString(o);
}
}

private static String normalizeString(String s) {
boolean isArray = (s.startsWith("{") && s.endsWith("}")) || (s.startsWith("[") && s.endsWith("]"));
if (isArray) {
s = s.replace(" ", "")
.replace("'", "")
.replace("\"", "")
.replace("{", "[")
.replace("}", "]");
}

return s;
}

private static void printCheck(String result, String expect, boolean ok) {
// System.out.println();
// System.out.println("--->");

System.out.println("result: " + result);
System.out.println("expect: " + expect);

System.out.println();
if (ok) {
System.out.println("比较结果为: 正确(right)");
} else {
System.out.println("比较结果为: 错误(error)");
}

// System.out.println();
// System.out.println("<---");
}

public static void runTestCases(Class<?> clazz) {
java.lang.reflect.Method[] methods = clazz.getDeclaredMethods();
java.util.Arrays.sort(methods, (o1, o2) -> {
return o1.getName().compareTo(o2.getName());
});
for (java.lang.reflect.Method method : methods) {
if (method.getName().startsWith("test")) {
System.out.println(String.format("--- %s --->", method.getName()));

Object object = null;
try {
object = method.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println(String.format("<--- %s ---", method.getName()));

if (object instanceof Boolean) {
Boolean ok = (Boolean) object;
if (!ok) {
break;
}
} else {
throw new RuntimeException(String.format("测试用例方法%s的返回值需要为布尔类型", method.getName()));
}
}
}
}

public static Object[] toArray(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0];
}

return list.toArray();
}

public static Object[][] toArrays(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0][0];
}

Object[][] arrays = new Object[list.size()][];
for (int i = 0; i < list.size(); i++) {
arrays[i] = toArray(list.get(i));
}

return arrays;
}

@SuppressWarnings("unchecked")
public static <T> T[] genArray(Class<T> clazz, int length) {
return (T[]) java.lang.reflect.Array.newInstance(clazz, length);
}

@SuppressWarnings("unchecked")
public static <T> T[][] genArrays(Class<T> clazz, int rows, int cols) {
T[] array = genArray(clazz, 0);

T[][] arrays = (T[][]) genArray(array.getClass(), rows);
for (int i = 0; i < arrays.length; i++) {
arrays[i] = genArray(clazz, cols);
}

return arrays;
}

public static <T> T[] toArray(java.util.List<T> list, Class<T> clazz) {
if (list == null || list.isEmpty()) {
return genArray(clazz, 0);
}

T[] array = genArray(clazz, list.size());
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}

return array;
}

public static <T> T[][] toArrays(java.util.List<java.util.List<T>> lists, Class<T> clazz) {
if (lists == null || lists.isEmpty()) {
return genArrays(clazz, 0, 0);
}

T[][] arrays = genArrays(clazz, lists.size(), 0);
for (int i = 0; i < lists.size(); i++) {
arrays[i] = toArray(lists.get(i), clazz);
}

return arrays;
}

public static <T> java.util.List<T> toList(T[] array) {
return java.util.Arrays.asList(array);
}

public static <T> java.util.List<java.util.List<T>> toLists(T[][] arrays) {
java.util.List<java.util.List<T>> lists = new java.util.ArrayList<>();
for (T[] array : arrays) {
lists.add(toList(array));
}

return lists;
}
}
}

完全二叉树的节点个数

题目描述

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

给你一棵 完全二叉树 的根节点 root ,求出该树的节点个数。

完全二叉树 的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2h 个节点。



示例 1:

输入:root = [1, 2, 3, 4, 5, 6]
输出:6
示例 2:

输入:root = []
输出:0
示例 3:

输入:root = [1]
输出:1


提示:

树中节点的数目范围是[0, 5 * 104]
0 <= Node.val <= 5 * 104
题目数据保证输入的树是 完全二叉树


进阶:遍历树来统计节点是一种时间复杂度为 O(n) 的简单解决方案。你可以设计一个更快的算法吗?

题目解答

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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
public class Solution {
public int countNodes(TreeNode root) {
if (root == null) {
return 0;
}

return 1 + countNodes(root.left) + countNodes(root.right);
}

static class TreeNode {
int val;
TreeNode left;
TreeNode right;

TreeNode() {
}

TreeNode(int val) {
this.val = val;
}

TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}

public static TreeNode genTree(Integer[] array) {
if (array.length == 0) {
return null;
}

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
TreeNode root = new TreeNode(array[0]);
queue.offer(root);

Integer v = null;
int i = 1;
while (i < array.length) {
TreeNode node = queue.poll();

TreeNode left = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;
TreeNode right = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;

// 数组中不包含空节点的子节点的写法(不标准的完全二叉树含空节点的层次遍历)
node.left = left;
node.right = right;
if (left != null) {
queue.offer(left);
}
if (right != null) {
queue.offer(right);
}

// 数组中包含空节点的子节点的写法(标准的完全二叉树含空节点的层次遍历)
// if (node != null) {
// node.left = left;
// node.right = right;
// }
// queue.offer(left);
// queue.offer(right);
}

return root;
}

public static Integer[] toArray(TreeNode root) {
if (root == null) {
return new Integer[0];
}

java.util.LinkedList<Integer> list = new java.util.LinkedList<>();

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
boolean hasValidNode = false;

int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();

if (node != null) {
list.add(node.val);

queue.offer(node.left);
queue.offer(node.right);

if (!hasValidNode) {
hasValidNode = node.left != null || node.right != null;
}
} else {
list.add(null);
}
}

if (!hasValidNode) {
// while (!queue.isEmpty()) {
// queue.poll();
// }

break;
}
}

while (!list.isEmpty() && list.get(list.size() - 1) == null) {
list.remove(list.size() - 1);
}

return list.toArray(new Integer[0]);
}
}
}

class TestMain {

public static void main(String[] args) {
TestUtils.runTestCases(TestCase.class);
}

public static class TestCase {

public static boolean testCase1() {
Integer[] nums = { 1, 2, 3, 4, 5, 6 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
int result = new Solution().countNodes(tree);
int expect = 6;

return TestUtils.check(result, expect);
}

public static boolean testCase2() {
Integer[] nums = {};

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
int result = new Solution().countNodes(tree);
int expect = 0;

return TestUtils.check(result, expect);
}

public static boolean testCase3() {
Integer[] nums = { 1 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
int result = new Solution().countNodes(tree);
int expect = 1;

return TestUtils.check(result, expect);
}
}

public static class TestUtils {

public static boolean check(Object result, Object expect) {
result = normalizeObject(result);
expect = normalizeObject(expect);
boolean ok = java.util.Objects.deepEquals(result, expect);
printCheck(toString(result), toString(expect), ok);
return ok;
}

public static boolean check(Object result, String expect) {
boolean ok = java.util.Objects.equals(normalizeString(toString(result)),
normalizeString(toString(expect)));
printCheck(normalizeString(toString(result)), normalizeString(toString(expect)), ok);
return ok;
}

private static Object normalizeObject(Object o) {
if (o instanceof java.util.List) {
java.util.List<?> list = (java.util.List<?>) o;
if (list != null && !list.isEmpty() && list.get(0) instanceof java.util.List) {
o = toArrays(list);
} else {
o = toArray(list);
}
}

return o;
}

private static String toString(Object o) {
if (o instanceof Object[]) {
return java.util.Arrays.deepToString((Object[]) o);
} else if (o instanceof int[]) {
return java.util.Arrays.toString((int[]) o);
} else if (o instanceof double[]) {
return java.util.Arrays.toString((double[]) o);
} else if (o instanceof char[]) {
return java.util.Arrays.toString((char[]) o);
} else {
return java.util.Objects.toString(o);
}
}

private static String normalizeString(String s) {
boolean isArray = (s.startsWith("{") && s.endsWith("}")) || (s.startsWith("[") && s.endsWith("]"));
if (isArray) {
s = s.replace(" ", "")
.replace("'", "")
.replace("\"", "")
.replace("{", "[")
.replace("}", "]");
}

return s;
}

private static void printCheck(String result, String expect, boolean ok) {
// System.out.println();
// System.out.println("--->");

System.out.println("result: " + result);
System.out.println("expect: " + expect);

System.out.println();
if (ok) {
System.out.println("比较结果为: 正确(right)");
} else {
System.out.println("比较结果为: 错误(error)");
}

// System.out.println();
// System.out.println("<---");
}

public static void runTestCases(Class<?> clazz) {
java.lang.reflect.Method[] methods = clazz.getDeclaredMethods();
java.util.Arrays.sort(methods, (o1, o2) -> {
return o1.getName().compareTo(o2.getName());
});
for (java.lang.reflect.Method method : methods) {
if (method.getName().startsWith("test")) {
System.out.println(String.format("--- %s --->", method.getName()));

Object object = null;
try {
object = method.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println(String.format("<--- %s ---", method.getName()));

if (object instanceof Boolean) {
Boolean ok = (Boolean) object;
if (!ok) {
break;
}
} else {
throw new RuntimeException(String.format("测试用例方法%s的返回值需要为布尔类型", method.getName()));
}
}
}
}

public static Object[] toArray(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0];
}

return list.toArray();
}

public static Object[][] toArrays(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0][0];
}

Object[][] arrays = new Object[list.size()][];
for (int i = 0; i < list.size(); i++) {
arrays[i] = toArray(list.get(i));
}

return arrays;
}

@SuppressWarnings("unchecked")
public static <T> T[] genArray(Class<T> clazz, int length) {
return (T[]) java.lang.reflect.Array.newInstance(clazz, length);
}

@SuppressWarnings("unchecked")
public static <T> T[][] genArrays(Class<T> clazz, int rows, int cols) {
T[] array = genArray(clazz, 0);

T[][] arrays = (T[][]) genArray(array.getClass(), rows);
for (int i = 0; i < arrays.length; i++) {
arrays[i] = genArray(clazz, cols);
}

return arrays;
}

public static <T> T[] toArray(java.util.List<T> list, Class<T> clazz) {
if (list == null || list.isEmpty()) {
return genArray(clazz, 0);
}

T[] array = genArray(clazz, list.size());
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}

return array;
}

public static <T> T[][] toArrays(java.util.List<java.util.List<T>> lists, Class<T> clazz) {
if (lists == null || lists.isEmpty()) {
return genArrays(clazz, 0, 0);
}

T[][] arrays = genArrays(clazz, lists.size(), 0);
for (int i = 0; i < lists.size(); i++) {
arrays[i] = toArray(lists.get(i), clazz);
}

return arrays;
}

public static <T> java.util.List<T> toList(T[] array) {
return java.util.Arrays.asList(array);
}

public static <T> java.util.List<java.util.List<T>> toLists(T[][] arrays) {
java.util.List<java.util.List<T>> lists = new java.util.ArrayList<>();
for (T[] array : arrays) {
lists.add(toList(array));
}

return lists;
}
}
}

进阶解法

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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
import java.util.Deque;
import java.util.LinkedList;

public class Solution {
public int countNodes(TreeNode root) {
if (root == null) {
return 0;
}

Deque<TreeNode> stack = new LinkedList<>();

TreeNode p = root;
while (p != null) {
stack.push(p);

p = p.right;
}

int nk = stack.size(); // 当前结点的深度
int tk = stack.size() + 1; // 树的深度

int totalMissedCount = countMissedNodes(stack.peek().right, nk + 1, tk);
while (!stack.isEmpty()) {
nk = stack.size();

TreeNode node = stack.pop();

int missedCount = countMissedNodes(node.left, nk + 1, tk);
if (missedCount == 0) {
break;
} else {
totalMissedCount = totalMissedCount + missedCount;
}
}

return (int) (Math.pow(2, tk) - 1 - totalMissedCount);
}

private int countMissedNodes(TreeNode node, int nk, int tk) {
if (nk == tk) {
if (node == null) {
return 1;
} else {
return 0;
}
} else {
if (node == null) {
return 0;
} else {
return countMissedNodes(node.left, nk + 1, tk) + countMissedNodes(node.right, nk + 1, tk);
}
}
}

static class TreeNode {
int val;
TreeNode left;
TreeNode right;

TreeNode() {
}

TreeNode(int val) {
this.val = val;
}

TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}

public static TreeNode genTree(Integer[] array) {
if (array.length == 0) {
return null;
}

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
TreeNode root = new TreeNode(array[0]);
queue.offer(root);

Integer v = null;
int i = 1;
while (i < array.length) {
TreeNode node = queue.poll();

TreeNode left = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;
TreeNode right = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;

// 数组中不包含空节点的子节点的写法(不标准的完全二叉树含空节点的层次遍历)
node.left = left;
node.right = right;
if (left != null) {
queue.offer(left);
}
if (right != null) {
queue.offer(right);
}

// 数组中包含空节点的子节点的写法(标准的完全二叉树含空节点的层次遍历)
// if (node != null) {
// node.left = left;
// node.right = right;
// }
// queue.offer(left);
// queue.offer(right);
}

return root;
}

public static Integer[] toArray(TreeNode root) {
if (root == null) {
return new Integer[0];
}

java.util.LinkedList<Integer> list = new java.util.LinkedList<>();

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
boolean hasValidNode = false;

int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();

if (node != null) {
list.add(node.val);

queue.offer(node.left);
queue.offer(node.right);

if (!hasValidNode) {
hasValidNode = node.left != null || node.right != null;
}
} else {
list.add(null);
}
}

if (!hasValidNode) {
// while (!queue.isEmpty()) {
// queue.poll();
// }

break;
}
}

while (!list.isEmpty() && list.get(list.size() - 1) == null) {
list.remove(list.size() - 1);
}

return list.toArray(new Integer[0]);
}
}
}

class TestMain {

public static void main(String[] args) {
TestUtils.runTestCases(TestCase.class);
}

public static class TestCase {

public static boolean testCase1() {
Integer[] nums = { 1, 2, 3, 4, 5, 6 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
int result = new Solution().countNodes(tree);
int expect = 6;

return TestUtils.check(result, expect);
}

public static boolean testCase2() {
Integer[] nums = {};

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
int result = new Solution().countNodes(tree);
int expect = 0;

return TestUtils.check(result, expect);
}

public static boolean testCase3() {
Integer[] nums = { 1 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
int result = new Solution().countNodes(tree);
int expect = 1;

return TestUtils.check(result, expect);
}
}

public static class TestUtils {

public static boolean check(Object result, Object expect) {
result = normalizeObject(result);
expect = normalizeObject(expect);
boolean ok = java.util.Objects.deepEquals(result, expect);
printCheck(toString(result), toString(expect), ok);
return ok;
}

public static boolean check(Object result, String expect) {
boolean ok = java.util.Objects.equals(normalizeString(toString(result)),
normalizeString(toString(expect)));
printCheck(normalizeString(toString(result)), normalizeString(toString(expect)), ok);
return ok;
}

private static Object normalizeObject(Object o) {
if (o instanceof java.util.List) {
java.util.List<?> list = (java.util.List<?>) o;
if (list != null && !list.isEmpty() && list.get(0) instanceof java.util.List) {
o = toArrays(list);
} else {
o = toArray(list);
}
}

return o;
}

private static String toString(Object o) {
if (o instanceof Object[]) {
return java.util.Arrays.deepToString((Object[]) o);
} else if (o instanceof int[]) {
return java.util.Arrays.toString((int[]) o);
} else if (o instanceof double[]) {
return java.util.Arrays.toString((double[]) o);
} else if (o instanceof char[]) {
return java.util.Arrays.toString((char[]) o);
} else {
return java.util.Objects.toString(o);
}
}

private static String normalizeString(String s) {
boolean isArray = (s.startsWith("{") && s.endsWith("}")) || (s.startsWith("[") && s.endsWith("]"));
if (isArray) {
s = s.replace(" ", "")
.replace("'", "")
.replace("\"", "")
.replace("{", "[")
.replace("}", "]");
}

return s;
}

private static void printCheck(String result, String expect, boolean ok) {
// System.out.println();
// System.out.println("--->");

System.out.println("result: " + result);
System.out.println("expect: " + expect);

System.out.println();
if (ok) {
System.out.println("比较结果为: 正确(right)");
} else {
System.out.println("比较结果为: 错误(error)");
}

// System.out.println();
// System.out.println("<---");
}

public static void runTestCases(Class<?> clazz) {
java.lang.reflect.Method[] methods = clazz.getDeclaredMethods();
java.util.Arrays.sort(methods, (o1, o2) -> {
return o1.getName().compareTo(o2.getName());
});
for (java.lang.reflect.Method method : methods) {
if (method.getName().startsWith("test")) {
System.out.println(String.format("--- %s --->", method.getName()));

Object object = null;
try {
object = method.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println(String.format("<--- %s ---", method.getName()));

if (object instanceof Boolean) {
Boolean ok = (Boolean) object;
if (!ok) {
break;
}
} else {
throw new RuntimeException(String.format("测试用例方法%s的返回值需要为布尔类型", method.getName()));
}
}
}
}

public static Object[] toArray(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0];
}

return list.toArray();
}

public static Object[][] toArrays(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0][0];
}

Object[][] arrays = new Object[list.size()][];
for (int i = 0; i < list.size(); i++) {
arrays[i] = toArray(list.get(i));
}

return arrays;
}

@SuppressWarnings("unchecked")
public static <T> T[] genArray(Class<T> clazz, int length) {
return (T[]) java.lang.reflect.Array.newInstance(clazz, length);
}

@SuppressWarnings("unchecked")
public static <T> T[][] genArrays(Class<T> clazz, int rows, int cols) {
T[] array = genArray(clazz, 0);

T[][] arrays = (T[][]) genArray(array.getClass(), rows);
for (int i = 0; i < arrays.length; i++) {
arrays[i] = genArray(clazz, cols);
}

return arrays;
}

public static <T> T[] toArray(java.util.List<T> list, Class<T> clazz) {
if (list == null || list.isEmpty()) {
return genArray(clazz, 0);
}

T[] array = genArray(clazz, list.size());
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}

return array;
}

public static <T> T[][] toArrays(java.util.List<java.util.List<T>> lists, Class<T> clazz) {
if (lists == null || lists.isEmpty()) {
return genArrays(clazz, 0, 0);
}

T[][] arrays = genArrays(clazz, lists.size(), 0);
for (int i = 0; i < lists.size(); i++) {
arrays[i] = toArray(lists.get(i), clazz);
}

return arrays;
}

public static <T> java.util.List<T> toList(T[] array) {
return java.util.Arrays.asList(array);
}

public static <T> java.util.List<java.util.List<T>> toLists(T[][] arrays) {
java.util.List<java.util.List<T>> lists = new java.util.ArrayList<>();
for (T[] array : arrays) {
lists.add(toList(array));
}

return lists;
}
}
}

二叉树的最近公共祖先

题目描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”



示例 1:

输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
输出:3
解释:节点 5 和节点 1 的最近公共祖先是节点 3 。
示例 2:

输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
输出:5
解释:节点 5 和节点 4 的最近公共祖先是节点 5 。因为根据定义最近公共祖先节点可以为节点本身。
示例 3:

输入:root = [1,2], p = 1, q = 2
输出:1

题目解答

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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
public class Solution {
private TreeNode aNode = null;

public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null) {
return null;
}

if (p == null || q == null) {
return null;
}

if (containsNode(root, p) && containsNode(root, q)) {
aNode = root;
}

TreeNode node;

node = lowestCommonAncestor(root.left, p, q);
if (node != null) {
aNode = node;
}

node = lowestCommonAncestor(root.right, p, q);
if (node != null) {
aNode = node;
}

if (aNode == null) {
aNode = root;
}

return aNode;
}

private boolean containsNode(TreeNode root, TreeNode node) {
if (root == null || node == null) {
return false;
}

if (node.val == root.val) {
return true;
}

return containsNode(root.left, node) || containsNode(root.right, node);
}

static class TreeNode {
int val;
TreeNode left;
TreeNode right;

TreeNode() {
}

TreeNode(int val) {
this.val = val;
}

TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}

public static TreeNode genTree(Integer[] array) {
if (array.length == 0) {
return null;
}

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
TreeNode root = new TreeNode(array[0]);
queue.offer(root);

Integer v = null;
int i = 1;
while (i < array.length) {
TreeNode node = queue.poll();

TreeNode left = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;
TreeNode right = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;

// 数组中不包含空节点的子节点的写法(不标准的完全二叉树含空节点的层次遍历)
node.left = left;
node.right = right;
if (left != null) {
queue.offer(left);
}
if (right != null) {
queue.offer(right);
}

// 数组中包含空节点的子节点的写法(标准的完全二叉树含空节点的层次遍历)
// if (node != null) {
// node.left = left;
// node.right = right;
// }
// queue.offer(left);
// queue.offer(right);
}

return root;
}

public static Integer[] toArray(TreeNode root) {
if (root == null) {
return new Integer[0];
}

java.util.LinkedList<Integer> list = new java.util.LinkedList<>();

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
boolean hasValidNode = false;

int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();

if (node != null) {
list.add(node.val);

queue.offer(node.left);
queue.offer(node.right);

if (!hasValidNode) {
hasValidNode = node.left != null || node.right != null;
}
} else {
list.add(null);
}
}

if (!hasValidNode) {
// while (!queue.isEmpty()) {
// queue.poll();
// }

break;
}
}

while (!list.isEmpty() && list.get(list.size() - 1) == null) {
list.remove(list.size() - 1);
}

return list.toArray(new Integer[0]);
}
}
}

class TestMain {

public static void main(String[] args) {
TestUtils.runTestCases(TestCase.class);
}

public static class TestCase {

public static boolean testCase1() {
Integer[] nums = { 3, 5, 1, 6, 2, 0, 8, null, null, 7, 4 };
Integer num1 = 5;
Integer num2 = 1;

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
Solution.TreeNode p = new Solution.TreeNode(num1);
Solution.TreeNode q = new Solution.TreeNode(num2);
Solution.TreeNode node = new Solution().lowestCommonAncestor(tree, p, q);
int result = node.val;
int expect = 3;

return TestUtils.check(result, expect);
}

public static boolean testCase2() {
Integer[] nums = { 3, 5, 1, 6, 2, 0, 8, null, null, 7, 4 };
Integer num1 = 5;
Integer num2 = 4;

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
Solution.TreeNode p = new Solution.TreeNode(num1);
Solution.TreeNode q = new Solution.TreeNode(num2);
Solution.TreeNode node = new Solution().lowestCommonAncestor(tree, p, q);
int result = node.val;
int expect = 5;

return TestUtils.check(result, expect);
}

public static boolean testCase3() {
Integer[] nums = { 1, 2 };
Integer num1 = 1;
Integer num2 = 2;

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
Solution.TreeNode p = new Solution.TreeNode(num1);
Solution.TreeNode q = new Solution.TreeNode(num2);
Solution.TreeNode node = new Solution().lowestCommonAncestor(tree, p, q);
int result = node.val;
int expect = 1;

return TestUtils.check(result, expect);
}

}

public static class TestUtils {

public static boolean check(Object result, Object expect) {
result = normalizeObject(result);
expect = normalizeObject(expect);
boolean ok = java.util.Objects.deepEquals(result, expect);
printCheck(toString(result), toString(expect), ok);
return ok;
}

public static boolean check(Object result, String expect) {
boolean ok = java.util.Objects.equals(normalizeString(toString(result)),
normalizeString(toString(expect)));
printCheck(normalizeString(toString(result)), normalizeString(toString(expect)), ok);
return ok;
}

private static Object normalizeObject(Object o) {
if (o instanceof java.util.List) {
java.util.List<?> list = (java.util.List<?>) o;
if (list != null && !list.isEmpty() && list.get(0) instanceof java.util.List) {
o = toArrays(list);
} else {
o = toArray(list);
}
}

return o;
}

private static String toString(Object o) {
if (o instanceof Object[]) {
return java.util.Arrays.deepToString((Object[]) o);
} else if (o instanceof int[]) {
return java.util.Arrays.toString((int[]) o);
} else if (o instanceof double[]) {
return java.util.Arrays.toString((double[]) o);
} else if (o instanceof char[]) {
return java.util.Arrays.toString((char[]) o);
} else {
return java.util.Objects.toString(o);
}
}

private static String normalizeString(String s) {
boolean isArray = (s.startsWith("{") && s.endsWith("}")) || (s.startsWith("[") && s.endsWith("]"));
if (isArray) {
s = s.replace(" ", "")
.replace("'", "")
.replace("\"", "")
.replace("{", "[")
.replace("}", "]");
}

return s;
}

private static void printCheck(String result, String expect, boolean ok) {
// System.out.println();
// System.out.println("--->");

System.out.println("result: " + result);
System.out.println("expect: " + expect);

System.out.println();
if (ok) {
System.out.println("比较结果为: 正确(right)");
} else {
System.out.println("比较结果为: 错误(error)");
}

// System.out.println();
// System.out.println("<---");
}

public static void runTestCases(Class<?> clazz) {
java.lang.reflect.Method[] methods = clazz.getDeclaredMethods();
java.util.Arrays.sort(methods, (o1, o2) -> {
return o1.getName().compareTo(o2.getName());
});
for (java.lang.reflect.Method method : methods) {
if (method.getName().startsWith("test")) {
System.out.println(String.format("--- %s --->", method.getName()));

Object object = null;
try {
object = method.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println(String.format("<--- %s ---", method.getName()));

if (object instanceof Boolean) {
Boolean ok = (Boolean) object;
if (!ok) {
break;
}
} else {
throw new RuntimeException(String.format("测试用例方法%s的返回值需要为布尔类型", method.getName()));
}
}
}
}

public static Object[] toArray(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0];
}

return list.toArray();
}

public static Object[][] toArrays(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0][0];
}

Object[][] arrays = new Object[list.size()][];
for (int i = 0; i < list.size(); i++) {
arrays[i] = toArray(list.get(i));
}

return arrays;
}

@SuppressWarnings("unchecked")
public static <T> T[] genArray(Class<T> clazz, int length) {
return (T[]) java.lang.reflect.Array.newInstance(clazz, length);
}

@SuppressWarnings("unchecked")
public static <T> T[][] genArrays(Class<T> clazz, int rows, int cols) {
T[] array = genArray(clazz, 0);

T[][] arrays = (T[][]) genArray(array.getClass(), rows);
for (int i = 0; i < arrays.length; i++) {
arrays[i] = genArray(clazz, cols);
}

return arrays;
}

public static <T> T[] toArray(java.util.List<T> list, Class<T> clazz) {
if (list == null || list.isEmpty()) {
return genArray(clazz, 0);
}

T[] array = genArray(clazz, list.size());
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}

return array;
}

public static <T> T[][] toArrays(java.util.List<java.util.List<T>> lists, Class<T> clazz) {
if (lists == null || lists.isEmpty()) {
return genArrays(clazz, 0, 0);
}

T[][] arrays = genArrays(clazz, lists.size(), 0);
for (int i = 0; i < lists.size(); i++) {
arrays[i] = toArray(lists.get(i), clazz);
}

return arrays;
}

public static <T> java.util.List<T> toList(T[] array) {
return java.util.Arrays.asList(array);
}

public static <T> java.util.List<java.util.List<T>> toLists(T[][] arrays) {
java.util.List<java.util.List<T>> lists = new java.util.ArrayList<>();
for (T[] array : arrays) {
lists.add(toList(array));
}

return lists;
}
}
}

进阶解法

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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;

public class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null) {
return null;
}

if (p == null || q == null) {
return null;
}

Map<Integer, TreeNode> map = new HashMap<>(); // 存储每个结点到双亲结点的映射
map.put(root.val, null);

int c = 0;

Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
TreeNode node = queue.poll();

if (node.val == p.val || node.val == q.val) {
if (c == 1) {
break;
} else {
c++;
}
}

if (node.left != null) {
queue.offer(node.left);

map.put(node.left.val, node);
}

if (node.right != null) {
queue.offer(node.right);

map.put(node.right.val, node);
}
}

List<TreeNode> list1 = new LinkedList<>();
List<TreeNode> list2 = new LinkedList<>();

TreeNode r;

r = p;
while (r != null) {
list1.add(0, r);

r = map.get(r.val);
}

r = q;
while (r != null) {
list2.add(0, r);

r = map.get(r.val);
}

TreeNode node = root;
int i = 0;
while (i < list1.size() && i < list2.size()) {
TreeNode node1 = list1.get(i);
TreeNode node2 = list2.get(i);

if (node1.val == node2.val) {
node = node1;
} else {
break;
}

i++;
}

return node;
}

static class TreeNode {
int val;
TreeNode left;
TreeNode right;

TreeNode() {
}

TreeNode(int val) {
this.val = val;
}

TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}

public static TreeNode genTree(Integer[] array) {
if (array.length == 0) {
return null;
}

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
TreeNode root = new TreeNode(array[0]);
queue.offer(root);

Integer v = null;
int i = 1;
while (i < array.length) {
TreeNode node = queue.poll();

TreeNode left = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;
TreeNode right = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;

// 数组中不包含空节点的子节点的写法(不标准的完全二叉树含空节点的层次遍历)
node.left = left;
node.right = right;
if (left != null) {
queue.offer(left);
}
if (right != null) {
queue.offer(right);
}

// 数组中包含空节点的子节点的写法(标准的完全二叉树含空节点的层次遍历)
// if (node != null) {
// node.left = left;
// node.right = right;
// }
// queue.offer(left);
// queue.offer(right);
}

return root;
}

public static Integer[] toArray(TreeNode root) {
if (root == null) {
return new Integer[0];
}

java.util.LinkedList<Integer> list = new java.util.LinkedList<>();

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
boolean hasValidNode = false;

int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();

if (node != null) {
list.add(node.val);

queue.offer(node.left);
queue.offer(node.right);

if (!hasValidNode) {
hasValidNode = node.left != null || node.right != null;
}
} else {
list.add(null);
}
}

if (!hasValidNode) {
// while (!queue.isEmpty()) {
// queue.poll();
// }

break;
}
}

while (!list.isEmpty() && list.get(list.size() - 1) == null) {
list.remove(list.size() - 1);
}

return list.toArray(new Integer[0]);
}
}
}

class TestMain {

public static void main(String[] args) {
TestUtils.runTestCases(TestCase.class);
}

public static class TestCase {

public static boolean testCase1() {
Integer[] nums = { 3, 5, 1, 6, 2, 0, 8, null, null, 7, 4 };
Integer num1 = 5;
Integer num2 = 1;

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
Solution.TreeNode p = new Solution.TreeNode(num1);
Solution.TreeNode q = new Solution.TreeNode(num2);
Solution.TreeNode node = new Solution().lowestCommonAncestor(tree, p, q);
int result = node.val;
int expect = 3;

return TestUtils.check(result, expect);
}

public static boolean testCase2() {
Integer[] nums = { 3, 5, 1, 6, 2, 0, 8, null, null, 7, 4 };
Integer num1 = 5;
Integer num2 = 4;

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
Solution.TreeNode p = new Solution.TreeNode(num1);
Solution.TreeNode q = new Solution.TreeNode(num2);
Solution.TreeNode node = new Solution().lowestCommonAncestor(tree, p, q);
int result = node.val;
int expect = 5;

return TestUtils.check(result, expect);
}

public static boolean testCase3() {
Integer[] nums = { 1, 2 };
Integer num1 = 1;
Integer num2 = 2;

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
Solution.TreeNode p = new Solution.TreeNode(num1);
Solution.TreeNode q = new Solution.TreeNode(num2);
Solution.TreeNode node = new Solution().lowestCommonAncestor(tree, p, q);
int result = node.val;
int expect = 1;

return TestUtils.check(result, expect);
}

}

public static class TestUtils {

public static boolean check(Object result, Object expect) {
result = normalizeObject(result);
expect = normalizeObject(expect);
boolean ok = java.util.Objects.deepEquals(result, expect);
printCheck(toString(result), toString(expect), ok);
return ok;
}

public static boolean check(Object result, String expect) {
boolean ok = java.util.Objects.equals(normalizeString(toString(result)),
normalizeString(toString(expect)));
printCheck(normalizeString(toString(result)), normalizeString(toString(expect)), ok);
return ok;
}

private static Object normalizeObject(Object o) {
if (o instanceof java.util.List) {
java.util.List<?> list = (java.util.List<?>) o;
if (list != null && !list.isEmpty() && list.get(0) instanceof java.util.List) {
o = toArrays(list);
} else {
o = toArray(list);
}
}

return o;
}

private static String toString(Object o) {
if (o instanceof Object[]) {
return java.util.Arrays.deepToString((Object[]) o);
} else if (o instanceof int[]) {
return java.util.Arrays.toString((int[]) o);
} else if (o instanceof double[]) {
return java.util.Arrays.toString((double[]) o);
} else if (o instanceof char[]) {
return java.util.Arrays.toString((char[]) o);
} else {
return java.util.Objects.toString(o);
}
}

private static String normalizeString(String s) {
boolean isArray = (s.startsWith("{") && s.endsWith("}")) || (s.startsWith("[") && s.endsWith("]"));
if (isArray) {
s = s.replace(" ", "")
.replace("'", "")
.replace("\"", "")
.replace("{", "[")
.replace("}", "]");
}

return s;
}

private static void printCheck(String result, String expect, boolean ok) {
// System.out.println();
// System.out.println("--->");

System.out.println("result: " + result);
System.out.println("expect: " + expect);

System.out.println();
if (ok) {
System.out.println("比较结果为: 正确(right)");
} else {
System.out.println("比较结果为: 错误(error)");
}

// System.out.println();
// System.out.println("<---");
}

public static void runTestCases(Class<?> clazz) {
java.lang.reflect.Method[] methods = clazz.getDeclaredMethods();
java.util.Arrays.sort(methods, (o1, o2) -> {
return o1.getName().compareTo(o2.getName());
});
for (java.lang.reflect.Method method : methods) {
if (method.getName().startsWith("test")) {
System.out.println(String.format("--- %s --->", method.getName()));

Object object = null;
try {
object = method.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println(String.format("<--- %s ---", method.getName()));

if (object instanceof Boolean) {
Boolean ok = (Boolean) object;
if (!ok) {
break;
}
} else {
throw new RuntimeException(String.format("测试用例方法%s的返回值需要为布尔类型", method.getName()));
}
}
}
}

public static Object[] toArray(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0];
}

return list.toArray();
}

public static Object[][] toArrays(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0][0];
}

Object[][] arrays = new Object[list.size()][];
for (int i = 0; i < list.size(); i++) {
arrays[i] = toArray(list.get(i));
}

return arrays;
}

@SuppressWarnings("unchecked")
public static <T> T[] genArray(Class<T> clazz, int length) {
return (T[]) java.lang.reflect.Array.newInstance(clazz, length);
}

@SuppressWarnings("unchecked")
public static <T> T[][] genArrays(Class<T> clazz, int rows, int cols) {
T[] array = genArray(clazz, 0);

T[][] arrays = (T[][]) genArray(array.getClass(), rows);
for (int i = 0; i < arrays.length; i++) {
arrays[i] = genArray(clazz, cols);
}

return arrays;
}

public static <T> T[] toArray(java.util.List<T> list, Class<T> clazz) {
if (list == null || list.isEmpty()) {
return genArray(clazz, 0);
}

T[] array = genArray(clazz, list.size());
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}

return array;
}

public static <T> T[][] toArrays(java.util.List<java.util.List<T>> lists, Class<T> clazz) {
if (lists == null || lists.isEmpty()) {
return genArrays(clazz, 0, 0);
}

T[][] arrays = genArrays(clazz, lists.size(), 0);
for (int i = 0; i < lists.size(); i++) {
arrays[i] = toArray(lists.get(i), clazz);
}

return arrays;
}

public static <T> java.util.List<T> toList(T[] array) {
return java.util.Arrays.asList(array);
}

public static <T> java.util.List<java.util.List<T>> toLists(T[][] arrays) {
java.util.List<java.util.List<T>> lists = new java.util.ArrayList<>();
for (T[] array : arrays) {
lists.add(toList(array));
}

return lists;
}
}
}

其他解法

解法1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Solution {

private TreeNode ans;

public Solution() {
this.ans = null;
}

private boolean dfs(TreeNode root, TreeNode p, TreeNode q) {
if (root == null) return false;
boolean lson = dfs(root.left, p, q);
boolean rson = dfs(root.right, p, q);
if ((lson && rson) || ((root.val == p.val || root.val == q.val) && (lson || rson))) {
ans = root;
}
return lson || rson || (root.val == p.val || root.val == q.val);
}

public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
this.dfs(root, p, q);
return this.ans;
}
}

解法2

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
class Solution {
Map<Integer, TreeNode> parent = new HashMap<Integer, TreeNode>();
Set<Integer> visited = new HashSet<Integer>();

public void dfs(TreeNode root) {
if (root.left != null) {
parent.put(root.left.val, root);
dfs(root.left);
}
if (root.right != null) {
parent.put(root.right.val, root);
dfs(root.right);
}
}

public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
dfs(root);
while (p != null) {
visited.add(p.val);
p = parent.get(p.val);
}
while (q != null) {
if (visited.contains(q.val)) {
return q;
}
q = parent.get(q.val);
}
return null;
}
}

二叉树的右视图

题目描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
给定一个二叉树的 根节点 root,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。



示例 1:

输入: [1,2,3,null,5,null,4]
输出: [1,3,4]
示例 2:

输入: [1,null,3]
输出: [1,3]
示例 3:

输入: []
输出: []


提示:

二叉树的节点个数的范围是 [0,100]
-100 <= Node.val <= 100

题目解答

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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

public class Solution {
public List<Integer> rightSideView(TreeNode root) {
if (root == null) {
return new LinkedList<>();
}

List<Integer> list = new LinkedList<>();

Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
int val = 0;

int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();

if (node.left != null) {
queue.offer(node.left);
}

if (node.right != null) {
queue.offer(node.right);
}

val = node.val;
}

list.add(val);
}

return list;
}

static class TreeNode {
int val;
TreeNode left;
TreeNode right;

TreeNode() {
}

TreeNode(int val) {
this.val = val;
}

TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}

public static TreeNode genTree(Integer[] array) {
if (array.length == 0) {
return null;
}

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
TreeNode root = new TreeNode(array[0]);
queue.offer(root);

Integer v = null;
int i = 1;
while (i < array.length) {
TreeNode node = queue.poll();

TreeNode left = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;
TreeNode right = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;

// 数组中不包含空节点的子节点的写法(不标准的完全二叉树含空节点的层次遍历)
node.left = left;
node.right = right;
if (left != null) {
queue.offer(left);
}
if (right != null) {
queue.offer(right);
}

// 数组中包含空节点的子节点的写法(标准的完全二叉树含空节点的层次遍历)
// if (node != null) {
// node.left = left;
// node.right = right;
// }
// queue.offer(left);
// queue.offer(right);
}

return root;
}

public static Integer[] toArray(TreeNode root) {
if (root == null) {
return new Integer[0];
}

java.util.LinkedList<Integer> list = new java.util.LinkedList<>();

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
boolean hasValidNode = false;

int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();

if (node != null) {
list.add(node.val);

queue.offer(node.left);
queue.offer(node.right);

if (!hasValidNode) {
hasValidNode = node.left != null || node.right != null;
}
} else {
list.add(null);
}
}

if (!hasValidNode) {
// while (!queue.isEmpty()) {
// queue.poll();
// }

break;
}
}

while (!list.isEmpty() && list.get(list.size() - 1) == null) {
list.remove(list.size() - 1);
}

return list.toArray(new Integer[0]);
}
}
}

class TestMain {

public static void main(String[] args) {
TestUtils.runTestCases(TestCase.class);
}

public static class TestCase {

public static boolean testCase1() {
Integer[] nums = { 1, 2, 3, null, 5, null, 4 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<Integer> result = new Solution().rightSideView(tree);
Integer[] expect = { 1, 3, 4 };

return TestUtils.check(result, expect);
}

public static boolean testCase2() {
Integer[] nums = { 1, null, 3 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<Integer> result = new Solution().rightSideView(tree);
Integer[] expect = { 1, 3 };

return TestUtils.check(result, expect);
}

public static boolean testCase3() {
Integer[] nums = {};

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<Integer> result = new Solution().rightSideView(tree);
Integer[] expect = {};

return TestUtils.check(result, expect);
}
}

public static class TestUtils {

public static boolean check(Object result, Object expect) {
result = normalizeObject(result);
expect = normalizeObject(expect);
boolean ok = java.util.Objects.deepEquals(result, expect);
printCheck(toString(result), toString(expect), ok);
return ok;
}

public static boolean check(Object result, String expect) {
boolean ok = java.util.Objects.equals(normalizeString(toString(result)),
normalizeString(toString(expect)));
printCheck(normalizeString(toString(result)), normalizeString(toString(expect)), ok);
return ok;
}

private static Object normalizeObject(Object o) {
if (o instanceof java.util.List) {
java.util.List<?> list = (java.util.List<?>) o;
if (list != null && !list.isEmpty() && list.get(0) instanceof java.util.List) {
o = toArrays(list);
} else {
o = toArray(list);
}
}

return o;
}

private static String toString(Object o) {
if (o instanceof Object[]) {
return java.util.Arrays.deepToString((Object[]) o);
} else if (o instanceof int[]) {
return java.util.Arrays.toString((int[]) o);
} else if (o instanceof double[]) {
return java.util.Arrays.toString((double[]) o);
} else if (o instanceof char[]) {
return java.util.Arrays.toString((char[]) o);
} else {
return java.util.Objects.toString(o);
}
}

private static String normalizeString(String s) {
boolean isArray = (s.startsWith("{") && s.endsWith("}")) || (s.startsWith("[") && s.endsWith("]"));
if (isArray) {
s = s.replace(" ", "")
.replace("'", "")
.replace("\"", "")
.replace("{", "[")
.replace("}", "]");
}

return s;
}

private static void printCheck(String result, String expect, boolean ok) {
// System.out.println();
// System.out.println("--->");

System.out.println("result: " + result);
System.out.println("expect: " + expect);

System.out.println();
if (ok) {
System.out.println("比较结果为: 正确(right)");
} else {
System.out.println("比较结果为: 错误(error)");
}

// System.out.println();
// System.out.println("<---");
}

public static void runTestCases(Class<?> clazz) {
java.lang.reflect.Method[] methods = clazz.getDeclaredMethods();
java.util.Arrays.sort(methods, (o1, o2) -> {
return o1.getName().compareTo(o2.getName());
});
for (java.lang.reflect.Method method : methods) {
if (method.getName().startsWith("test")) {
System.out.println(String.format("--- %s --->", method.getName()));

Object object = null;
try {
object = method.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println(String.format("<--- %s ---", method.getName()));

if (object instanceof Boolean) {
Boolean ok = (Boolean) object;
if (!ok) {
break;
}
} else {
throw new RuntimeException(String.format("测试用例方法%s的返回值需要为布尔类型", method.getName()));
}
}
}
}

public static Object[] toArray(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0];
}

return list.toArray();
}

public static Object[][] toArrays(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0][0];
}

Object[][] arrays = new Object[list.size()][];
for (int i = 0; i < list.size(); i++) {
arrays[i] = toArray(list.get(i));
}

return arrays;
}

@SuppressWarnings("unchecked")
public static <T> T[] genArray(Class<T> clazz, int length) {
return (T[]) java.lang.reflect.Array.newInstance(clazz, length);
}

@SuppressWarnings("unchecked")
public static <T> T[][] genArrays(Class<T> clazz, int rows, int cols) {
T[] array = genArray(clazz, 0);

T[][] arrays = (T[][]) genArray(array.getClass(), rows);
for (int i = 0; i < arrays.length; i++) {
arrays[i] = genArray(clazz, cols);
}

return arrays;
}

public static <T> T[] toArray(java.util.List<T> list, Class<T> clazz) {
if (list == null || list.isEmpty()) {
return genArray(clazz, 0);
}

T[] array = genArray(clazz, list.size());
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}

return array;
}

public static <T> T[][] toArrays(java.util.List<java.util.List<T>> lists, Class<T> clazz) {
if (lists == null || lists.isEmpty()) {
return genArrays(clazz, 0, 0);
}

T[][] arrays = genArrays(clazz, lists.size(), 0);
for (int i = 0; i < lists.size(); i++) {
arrays[i] = toArray(lists.get(i), clazz);
}

return arrays;
}

public static <T> java.util.List<T> toList(T[] array) {
return java.util.Arrays.asList(array);
}

public static <T> java.util.List<java.util.List<T>> toLists(T[][] arrays) {
java.util.List<java.util.List<T>> lists = new java.util.ArrayList<>();
for (T[] array : arrays) {
lists.add(toList(array));
}

return lists;
}
}
}

其他解法

解法1

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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;

public class Solution {
public List<Integer> rightSideView(TreeNode root) {
if (root == null) {
return new LinkedList<>();
}

List<Integer> list = new LinkedList<>();

TreeNode preNode = null;

Map<TreeNode, Integer> map = new HashMap<>(); // 存储每个结点的层次
map.put(root, 1);

Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
TreeNode node = queue.poll();

if (node.left != null) {
queue.offer(node.left);

map.put(node.left, map.get(node) + 1);
}

if (node.right != null) {
queue.offer(node.right);

map.put(node.right, map.get(node) + 1);
}

if (preNode != null && map.get(node) == map.get(preNode)) {
// do nothng
} else {
if (preNode != null) {
list.add(preNode.val);
}
}

preNode = node;
}

if (preNode != null) {
list.add(preNode.val);
}

return list;
}

static class TreeNode {
int val;
TreeNode left;
TreeNode right;

TreeNode() {
}

TreeNode(int val) {
this.val = val;
}

TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}

public static TreeNode genTree(Integer[] array) {
if (array.length == 0) {
return null;
}

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
TreeNode root = new TreeNode(array[0]);
queue.offer(root);

Integer v = null;
int i = 1;
while (i < array.length) {
TreeNode node = queue.poll();

TreeNode left = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;
TreeNode right = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;

// 数组中不包含空节点的子节点的写法(不标准的完全二叉树含空节点的层次遍历)
node.left = left;
node.right = right;
if (left != null) {
queue.offer(left);
}
if (right != null) {
queue.offer(right);
}

// 数组中包含空节点的子节点的写法(标准的完全二叉树含空节点的层次遍历)
// if (node != null) {
// node.left = left;
// node.right = right;
// }
// queue.offer(left);
// queue.offer(right);
}

return root;
}

public static Integer[] toArray(TreeNode root) {
if (root == null) {
return new Integer[0];
}

java.util.LinkedList<Integer> list = new java.util.LinkedList<>();

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
boolean hasValidNode = false;

int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();

if (node != null) {
list.add(node.val);

queue.offer(node.left);
queue.offer(node.right);

if (!hasValidNode) {
hasValidNode = node.left != null || node.right != null;
}
} else {
list.add(null);
}
}

if (!hasValidNode) {
// while (!queue.isEmpty()) {
// queue.poll();
// }

break;
}
}

while (!list.isEmpty() && list.get(list.size() - 1) == null) {
list.remove(list.size() - 1);
}

return list.toArray(new Integer[0]);
}
}
}

class TestMain {

public static void main(String[] args) {
TestUtils.runTestCases(TestCase.class);
}

public static class TestCase {

public static boolean testCase1() {
Integer[] nums = { 1, 2, 3, null, 5, null, 4 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<Integer> result = new Solution().rightSideView(tree);
Integer[] expect = { 1, 3, 4 };

return TestUtils.check(result, expect);
}

public static boolean testCase2() {
Integer[] nums = { 1, null, 3 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<Integer> result = new Solution().rightSideView(tree);
Integer[] expect = { 1, 3 };

return TestUtils.check(result, expect);
}

public static boolean testCase3() {
Integer[] nums = {};

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<Integer> result = new Solution().rightSideView(tree);
Integer[] expect = {};

return TestUtils.check(result, expect);
}
}

public static class TestUtils {

public static boolean check(Object result, Object expect) {
result = normalizeObject(result);
expect = normalizeObject(expect);
boolean ok = java.util.Objects.deepEquals(result, expect);
printCheck(toString(result), toString(expect), ok);
return ok;
}

public static boolean check(Object result, String expect) {
boolean ok = java.util.Objects.equals(normalizeString(toString(result)),
normalizeString(toString(expect)));
printCheck(normalizeString(toString(result)), normalizeString(toString(expect)), ok);
return ok;
}

private static Object normalizeObject(Object o) {
if (o instanceof java.util.List) {
java.util.List<?> list = (java.util.List<?>) o;
if (list != null && !list.isEmpty() && list.get(0) instanceof java.util.List) {
o = toArrays(list);
} else {
o = toArray(list);
}
}

return o;
}

private static String toString(Object o) {
if (o instanceof Object[]) {
return java.util.Arrays.deepToString((Object[]) o);
} else if (o instanceof int[]) {
return java.util.Arrays.toString((int[]) o);
} else if (o instanceof double[]) {
return java.util.Arrays.toString((double[]) o);
} else if (o instanceof char[]) {
return java.util.Arrays.toString((char[]) o);
} else {
return java.util.Objects.toString(o);
}
}

private static String normalizeString(String s) {
boolean isArray = (s.startsWith("{") && s.endsWith("}")) || (s.startsWith("[") && s.endsWith("]"));
if (isArray) {
s = s.replace(" ", "")
.replace("'", "")
.replace("\"", "")
.replace("{", "[")
.replace("}", "]");
}

return s;
}

private static void printCheck(String result, String expect, boolean ok) {
// System.out.println();
// System.out.println("--->");

System.out.println("result: " + result);
System.out.println("expect: " + expect);

System.out.println();
if (ok) {
System.out.println("比较结果为: 正确(right)");
} else {
System.out.println("比较结果为: 错误(error)");
}

// System.out.println();
// System.out.println("<---");
}

public static void runTestCases(Class<?> clazz) {
java.lang.reflect.Method[] methods = clazz.getDeclaredMethods();
java.util.Arrays.sort(methods, (o1, o2) -> {
return o1.getName().compareTo(o2.getName());
});
for (java.lang.reflect.Method method : methods) {
if (method.getName().startsWith("test")) {
System.out.println(String.format("--- %s --->", method.getName()));

Object object = null;
try {
object = method.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println(String.format("<--- %s ---", method.getName()));

if (object instanceof Boolean) {
Boolean ok = (Boolean) object;
if (!ok) {
break;
}
} else {
throw new RuntimeException(String.format("测试用例方法%s的返回值需要为布尔类型", method.getName()));
}
}
}
}

public static Object[] toArray(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0];
}

return list.toArray();
}

public static Object[][] toArrays(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0][0];
}

Object[][] arrays = new Object[list.size()][];
for (int i = 0; i < list.size(); i++) {
arrays[i] = toArray(list.get(i));
}

return arrays;
}

@SuppressWarnings("unchecked")
public static <T> T[] genArray(Class<T> clazz, int length) {
return (T[]) java.lang.reflect.Array.newInstance(clazz, length);
}

@SuppressWarnings("unchecked")
public static <T> T[][] genArrays(Class<T> clazz, int rows, int cols) {
T[] array = genArray(clazz, 0);

T[][] arrays = (T[][]) genArray(array.getClass(), rows);
for (int i = 0; i < arrays.length; i++) {
arrays[i] = genArray(clazz, cols);
}

return arrays;
}

public static <T> T[] toArray(java.util.List<T> list, Class<T> clazz) {
if (list == null || list.isEmpty()) {
return genArray(clazz, 0);
}

T[] array = genArray(clazz, list.size());
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}

return array;
}

public static <T> T[][] toArrays(java.util.List<java.util.List<T>> lists, Class<T> clazz) {
if (lists == null || lists.isEmpty()) {
return genArrays(clazz, 0, 0);
}

T[][] arrays = genArrays(clazz, lists.size(), 0);
for (int i = 0; i < lists.size(); i++) {
arrays[i] = toArray(lists.get(i), clazz);
}

return arrays;
}

public static <T> java.util.List<T> toList(T[] array) {
return java.util.Arrays.asList(array);
}

public static <T> java.util.List<java.util.List<T>> toLists(T[][] arrays) {
java.util.List<java.util.List<T>> lists = new java.util.ArrayList<>();
for (T[] array : arrays) {
lists.add(toList(array));
}

return lists;
}
}
}

二叉树的层平均值

题目描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
给定一个非空二叉树的根节点 root , 以数组的形式返回每一层节点的平均值。与实际答案相差 10-5 以内的答案可以被接受。



示例 1:

输入:root = [3,9,20,null,null,15,7]
输出:[3.00000,14.50000,11.00000]
解释:第 0 层的平均值为 3,第 1 层的平均值为 14.5,第 2 层的平均值为 11 。
因此返回 [3, 14.5, 11] 。
示例 2:

输入:root = [3,9,20,15,7]
输出:[3.00000,14.50000,11.00000]


提示:

树中节点数量在 [1, 104] 范围内
-231 <= Node.val <= 231 - 1

题目解答

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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

public class Solution {
public List<Double> averageOfLevels(TreeNode root) {
if (root == null) {
return new LinkedList<>();
}

List<Double> list = new LinkedList<>();

Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
List<Integer> values = new LinkedList<>(); // 临时用来存储每一层的值,避免直接相加溢出的问题

int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();

if (node.left != null) {
queue.offer(node.left);
}

if (node.right != null) {
queue.offer(node.right);
}

values.add(node.val);
}

// 在不溢出(负数方向溢出和正数方向溢出)的情况下尽可能的累加
// 一要避免先累加再平均时分子太大导致加法结果溢出范围
// 因为case里面出现了分子都是最大整数值导致结果溢出范围为负的情况
// 二要避免先平均再累加时分子太小导致除法结果误差太大
// 因为case里面出现了大数据量累加时导致结果误差累计之后不满足要求

int sum = 0;
double avg = 0;
int cnt = values.size();

int i = 0;
int j = cnt - 1;

values.sort(null);
while (i <= j) {
if (sum <= 0 && values.get(j) >= 0) {
sum = sum + values.get(j);
j--;
} else if (sum >= 0 && values.get(i) <= 0) {
sum = sum + values.get(i);
i++;
} else if (sum == 0) {
sum = values.get(i++);
// sum = values.get(j--);

avg = avg + sum / (double) cnt;

sum = 0;
} else {
avg = avg + sum / (double) cnt;

sum = 0;
}
}

if (sum != 0) {
avg = avg + sum / (double) cnt;
}

list.add(avg);
}

return list;
}

static class TreeNode {
int val;
TreeNode left;
TreeNode right;

TreeNode() {
}

TreeNode(int val) {
this.val = val;
}

TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}

public static TreeNode genTree(Integer[] array) {
if (array.length == 0) {
return null;
}

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
TreeNode root = new TreeNode(array[0]);
queue.offer(root);

Integer v = null;
int i = 1;
while (i < array.length) {
TreeNode node = queue.poll();

TreeNode left = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;
TreeNode right = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;

// 数组中不包含空节点的子节点的写法(不标准的完全二叉树含空节点的层次遍历)
node.left = left;
node.right = right;
if (left != null) {
queue.offer(left);
}
if (right != null) {
queue.offer(right);
}

// 数组中包含空节点的子节点的写法(标准的完全二叉树含空节点的层次遍历)
// if (node != null) {
// node.left = left;
// node.right = right;
// }
// queue.offer(left);
// queue.offer(right);
}

return root;
}

public static Integer[] toArray(TreeNode root) {
if (root == null) {
return new Integer[0];
}

java.util.LinkedList<Integer> list = new java.util.LinkedList<>();

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
boolean hasValidNode = false;

int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();

if (node != null) {
list.add(node.val);

queue.offer(node.left);
queue.offer(node.right);

if (!hasValidNode) {
hasValidNode = node.left != null || node.right != null;
}
} else {
list.add(null);
}
}

if (!hasValidNode) {
// while (!queue.isEmpty()) {
// queue.poll();
// }

break;
}
}

while (!list.isEmpty() && list.get(list.size() - 1) == null) {
list.remove(list.size() - 1);
}

return list.toArray(new Integer[0]);
}
}
}

class TestMain {

public static void main(String[] args) {
TestUtils.runTestCases(TestCase.class);
}

public static class TestCase {

public static boolean testCase1() {
Integer[] nums = { 3, 9, 20, null, null, 15, 7 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<Double> result = new Solution().averageOfLevels(tree);
Double[] expect = { 3.0, 14.5, 11.0 };

return TestUtils.check(result, expect);
}

public static boolean testCase2() {
Integer[] nums = { 3, 9, 20, 15, 7 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<Double> result = new Solution().averageOfLevels(tree);
Double[] expect = { 3.0, 14.5, 11.0 };

return TestUtils.check(result, expect);
}

public static boolean testCase3() {
Integer[] nums = { 2147483647, 2147483647, 2147483647 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<Double> result = new Solution().averageOfLevels(tree);
Double[] expect = { 2.147483647E9, 2.147483647E9 };

return TestUtils.check(result, expect);
}

public static boolean testCase4() {
Integer[] nums = { 1, 1, 1, 1, 1, 1, 1 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<Double> result = new Solution().averageOfLevels(tree);
Double[] expect = { 1.0, 1.0, 1.0 };

return TestUtils.check(result, expect);
}

public static boolean testCase5() {
Integer[] nums = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2147483647, 2147483647, 2147483647, 2147483643, 2147483645,
2147483646, 2147483646, 2147483624, 2147483646, 2147483647, 2147483646, 2147483647, 2147483647,
2147483631, 2147483647, 2147483647, 2147483647, 2147483647, 2147483631, 2147483647, 2147483647,
2147483647, 2147483647, 2147483646, 2147483646, 2147483614, 2147483646, 2147483647, 2147483646,
2147483647, 2147483646, 2147483647, 2147483646, 2147483647, 2147483646, 2147483647, 2147483646,
2147483647, 2147483646, 2147483647, 2147483646, 2147483647, 2147483646, 2147483647, 2147483646,
2147483647, 2147483646, 2147483647, 2147483644, 2147483644, 2147483647, 2147483647, 2147483644,
2147483647, 2147483647, 2147483644, 2147483647, 2147483647, 2147483644, 2147483647, 2147483647,
2147483644, 2147483647, 2147483647, 2147483644, 2147483647, 2147483647, 2147483644, 2147483647,
2147483647, 2147483644, 2147483647, 2147483647, 2147483644, 2147483647, 2147483647, 2147483644,
2147483647, 2147483647, 2147483644, 2147483647, 2147483647, 2147483644, 2147483647, 2147483647,
2147483644, 2147483647, 2147483647, 2147483644, 2147483647, 2147483647, 2147483644, 2147483647,
2147483647, 2147483642, 2147483647, 2147483647, 2147483647, 2147483636, 2147483647, 2147483647,
2147483647, 2147483647, 2147483647, 2147483647, 2147483636, 2147483647, 2147483647, 2147483647,
2147483647, 2147483647, 2147483647, 2147483636, 2147483647, 2147483647, 2147483647, 2147483647,
2147483647, 2147483647, 2147483636, 2147483647, 2147483647, 2147483647, 2147483647, 2147483647,
2147483647, 2147483636, 2147483647, 2147483647, 2147483647, 2147483647, 2147483647, 2147483647,
2147483636, 2147483647, 2147483647, 2147483647, 2147483647, 2147483647, 2147483647, 2147483636,
2147483647, 2147483647, 2147483647, 2147483647, 2147483647, 2147483647, 2147483636, 2147483647,
2147483647, 2147483647, 2147483647, 2147483647, 2147483647, 2147483636, 2147483647, 2147483647,
2147483647, 2147483647, 2147483647, 2147483647, 2147483636, 2147483647, 2147483647, 2147483647,
2147483647, 2147483647, 2147483647, 2147483636, 2147483647, 2147483647, 2147483647, 2147483647,
2147483647, 2147483647, 2147483636, 2147483647, 2147483647, 2147483647, 2147483647, 2147483647,
2147483647, 2147483636, 2147483647, 2147483647, 2147483647, 2147483647, 2147483647, 2147483647,
2147483642, 2147483642, 2147483647, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642,
2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642,
2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642,
2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642,
2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642,
2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642,
2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642,
2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642,
2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642,
2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642,
2147483642, 2147483642, 2147483647, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642,
2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642,
2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642,
2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642,
2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642,
2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642,
2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642,
2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642,
2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642,
2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642,
2147483642, 2147483642, 2147483647, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642,
2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642,
2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642,
2147483642, 2147483642, 2147483642, 2147483642, 2147483642, -2147483647, -2147483647, -2147483647,
-2147483647, -2147483647, -2147483644, -2147483647, -2147483647, -2147483644, -2147483647,
-2147483647,
-2147483644, -2147483647, -2147483647, -2147483644, -2147483647, -2147483647, -2147483644,
-2147483647,
-2147483647, -2147483644, -2147483647, -2147483647, -2147483644, -2147483647, -2147483647,
-2147483644,
-2147483647, -2147483647, -2147483644, -2147483647, -2147483647, -2147483644, -2147483647,
-2147483647,
-2147483644, -2147483647, -2147483647, -2147483644, -2147483647, -2147483647, -2147483644,
-2147483647,
-2147483647, -2147483644, -2147483647, -2147483647, -2147483644, -2147483647, -2147483647,
-2147483644,
-2147483647, -2147483647, -2147483644, -2147483647, -2147483647, -2147483644, -2147483647,
-2147483647,
-2147483644, -2147483647, -2147483647, -2147483644, -2147483647, -2147483647, -2147483644,
-2147483647,
-2147483647, -2147483644, -2147483647, -2147483647, -2147483644, -2147483647, -2147483647,
-2147483644,
-2147483647, -2147483647, -2147483644, -2147483647, -2147483647, -2147483644, -2147483647,
-2147483647,
-2147483644, -2147483647, -2147483647, -2147483644, -2147483647, -2147483647, -2147483644,
-2147483647,
-2147483647, -2147483644, -2147483647, -2147483647, -2147483644, -2147483647, -2147483647,
-2147483644,
-2147483647, -2147483647, -2147483644, -2147483647, -2147483647, -2147483644, -2147483647,
-2147483647,
-2147483644, -2147483647, -2147483647, -2147483644, -2147483647, -2147483647, -2147483644,
-2147483647,
-2147483647, -2147483644, -2147483647, -2147483647, -2147483644, -2147483647, -2147483647,
-2147483644,
-2147483647, -2147483647, -2147483644, -2147483647, -2147483647, -2147483644, -2147483647,
-2147483647,
-2147483644, -2147483647, -2147483647, -2147483644, -2147483647, -2147483647, -2147483644,
-2147483647,
-2147483647, -2147483644, -2147483647, -2147483647, -2147483644, -2147483647, -2147483647,
-2147483644,
-2147483647, -2147483647, -2147483644, -2147483647, -2147483647, -2147483644, -2147483647,
-2147483647,
-2147483644, -2147483647, -2147483647, -2147483644, -2147483647, -2147483647, -2147483644,
-2147483647,
-2147483647, -2147483644, -2147483647, -2147483647, -2147483644, -2147483647, -2147483647,
-2147483644,
-2147483647, -2147483647, -2147483644, -2147483647, -2147483647, -2147483644, -2147483647,
-2147483647,
-2147483644, -2147483647, -2147483647, -2147483644, -2147483647, -2147483647, -2147483644,
-2147483647,
-2147483647, -2147483638, -2147483642, -2147483642, -2147483642, -2147483642, -2147483642,
-2147483642,
-2147483642, -2147483642, -2147483642, -2147483643, -2147483642, -2147483642, -2147483642,
-2147483642,
-2147483642, -2147483642, -2147483642, -2147483642, -2147483642, -2147483642, -2147483642,
-2147483642,
-2147483642, -2147483642, -2147483642, -2147483643, -2147483642, -2147483642, -2147483642,
-2147483642,
-2147483642, -2147483642, -2147483642, -2147483642, -2147483642, -2147483642, -2147483642,
-2147483642,
-2147483642, -2147483642, -2147483642, -2147483643, -2147483642, -2147483642, -2147483642,
-2147483642,
-2147483642, -2147483642, -2147483642, -2147483642, -2147483642, -2147483642, -2147483642,
-2147483642,
-2147483642, -2147483642, -2147483642, -2147483643, -2147483642, -2147483642, -2147483642,
-2147483642,
-2147483642, -2147483642, -2147483642, -2147483642, -2147483642, -2147483642, -2147483642,
-2147483642,
-2147483642, -2147483642, -2147483642, -2147483643, -2147483642, -2147483642, -2147483642,
-2147483642,
-2147483642, -2147483642, -2147483642, -2147483642, -2147483642, -2147483642, -2147483642,
-2147483642,
-2147483642, -2147483642, -2147483642, -2147483643, -2147483642, -2147483642, -2147483642,
-2147483642,
-2147483598, -2147483647, -2147483647, -2147483647, -2147483647, -2147483645, -2147483647,
-2147483647,
-2147483647, -2147483645, -2147483647, -2147483647, -2147483647, -2147483645, -2147483647,
-2147483647,
-2147483647, -2147483645, -2147483647, -2147483647, -2147483647, -2147483645, -2147483647,
-2147483647,
-2147483647, -2147483645, -2147483647, -2147483647, -2147483647, -2147483645, -2147483647,
-2147483647,
-2147483647, -2147483645, -2147483647, -2147483647, -2147483647, -2147483645, -2147483647,
-2147483647,
-2147483647, -2147483645, -2147483647, -2147483647, -2147483647, -2147483645, -2147483647,
-2147483647,
-2147483647, -2147483647, -2147483647, -2147483647, -2147483647, -2147483647, -2147483647,
-2147483647,
-2147483647, -2147483647, -2147483644, -2147483647, -2147483647, -2147483644, -2147483647,
-2147483647,
-2147483644, -2147483647, -2147483647, -2147483644, -2147483647, -2147483647, -2147483644,
-2147483600,
-2147483646, -2147483646, -2147483646, -2147483646, -2147483646, -2147483646, -2147483646,
-2147483646,
-2147483646, -2147483646, -2147483646, -2147483647, -2147483647, -2147483525, -2147483647,
-2147483647,
-2147483644, -2147483647, -2147483647, -2147483647, -2147483646, -2147483647, -2147483336 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<Double> result = new Solution().averageOfLevels(tree);
Double[] expect = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };

return TestUtils.check(result, expect);
}
}

public static class TestUtils {

public static boolean check(Object result, Object expect) {
result = normalizeObject(result);
expect = normalizeObject(expect);
boolean ok = java.util.Objects.deepEquals(result, expect);
printCheck(toString(result), toString(expect), ok);
return ok;
}

public static boolean check(Object result, String expect) {
boolean ok = java.util.Objects.equals(normalizeString(toString(result)),
normalizeString(toString(expect)));
printCheck(normalizeString(toString(result)), normalizeString(toString(expect)), ok);
return ok;
}

private static Object normalizeObject(Object o) {
if (o instanceof java.util.List) {
java.util.List<?> list = (java.util.List<?>) o;
if (list != null && !list.isEmpty() && list.get(0) instanceof java.util.List) {
o = toArrays(list);
} else {
o = toArray(list);
}
}

return o;
}

private static String toString(Object o) {
if (o instanceof Object[]) {
return java.util.Arrays.deepToString((Object[]) o);
} else if (o instanceof int[]) {
return java.util.Arrays.toString((int[]) o);
} else if (o instanceof double[]) {
return java.util.Arrays.toString((double[]) o);
} else if (o instanceof char[]) {
return java.util.Arrays.toString((char[]) o);
} else {
return java.util.Objects.toString(o);
}
}

private static String normalizeString(String s) {
boolean isArray = (s.startsWith("{") && s.endsWith("}")) || (s.startsWith("[") && s.endsWith("]"));
if (isArray) {
s = s.replace(" ", "")
.replace("'", "")
.replace("\"", "")
.replace("{", "[")
.replace("}", "]");
}

return s;
}

private static void printCheck(String result, String expect, boolean ok) {
// System.out.println();
// System.out.println("--->");

System.out.println("result: " + result);
System.out.println("expect: " + expect);

System.out.println();
if (ok) {
System.out.println("比较结果为: 正确(right)");
} else {
System.out.println("比较结果为: 错误(error)");
}

// System.out.println();
// System.out.println("<---");
}

public static void runTestCases(Class<?> clazz) {
java.lang.reflect.Method[] methods = clazz.getDeclaredMethods();
java.util.Arrays.sort(methods, (o1, o2) -> {
return o1.getName().compareTo(o2.getName());
});
for (java.lang.reflect.Method method : methods) {
if (method.getName().startsWith("test")) {
System.out.println(String.format("--- %s --->", method.getName()));

Object object = null;
try {
object = method.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println(String.format("<--- %s ---", method.getName()));

if (object instanceof Boolean) {
Boolean ok = (Boolean) object;
if (!ok) {
break;
}
} else {
throw new RuntimeException(String.format("测试用例方法%s的返回值需要为布尔类型", method.getName()));
}
}
}
}

public static Object[] toArray(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0];
}

return list.toArray();
}

public static Object[][] toArrays(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0][0];
}

Object[][] arrays = new Object[list.size()][];
for (int i = 0; i < list.size(); i++) {
arrays[i] = toArray(list.get(i));
}

return arrays;
}

@SuppressWarnings("unchecked")
public static <T> T[] genArray(Class<T> clazz, int length) {
return (T[]) java.lang.reflect.Array.newInstance(clazz, length);
}

@SuppressWarnings("unchecked")
public static <T> T[][] genArrays(Class<T> clazz, int rows, int cols) {
T[] array = genArray(clazz, 0);

T[][] arrays = (T[][]) genArray(array.getClass(), rows);
for (int i = 0; i < arrays.length; i++) {
arrays[i] = genArray(clazz, cols);
}

return arrays;
}

public static <T> T[] toArray(java.util.List<T> list, Class<T> clazz) {
if (list == null || list.isEmpty()) {
return genArray(clazz, 0);
}

T[] array = genArray(clazz, list.size());
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}

return array;
}

public static <T> T[][] toArrays(java.util.List<java.util.List<T>> lists, Class<T> clazz) {
if (lists == null || lists.isEmpty()) {
return genArrays(clazz, 0, 0);
}

T[][] arrays = genArrays(clazz, lists.size(), 0);
for (int i = 0; i < lists.size(); i++) {
arrays[i] = toArray(lists.get(i), clazz);
}

return arrays;
}

public static <T> java.util.List<T> toList(T[] array) {
return java.util.Arrays.asList(array);
}

public static <T> java.util.List<java.util.List<T>> toLists(T[][] arrays) {
java.util.List<java.util.List<T>> lists = new java.util.ArrayList<>();
for (T[] array : arrays) {
lists.add(toList(array));
}

return lists;
}
}
}

其他解法

解法1

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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;

public class Solution {
public List<Double> averageOfLevels(TreeNode root) {
if (root == null) {
return new LinkedList<>();
}

List<Double> list = new LinkedList<>();
List<Integer> values = new LinkedList<>(); // 临时用来存储每一层的值,避免直接相加溢出的问题

int preLevel = 1;

Map<TreeNode, Integer> map = new HashMap<>(); // 存储每个结点的层次
map.put(root, 1);

Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
TreeNode node = queue.poll();

if (node.left != null) {
queue.offer(node.left);

map.put(node.left, map.get(node) + 1);
}

if (node.right != null) {
queue.offer(node.right);

map.put(node.right, map.get(node) + 1);
}

if (map.get(node) == preLevel) {
values.add(node.val);
} else {
// 在不溢出(负数方向溢出和正数方向溢出)的情况下尽可能的累加
// 一要避免先累加再平均时分子太大导致加法结果溢出范围
// 因为case里面出现了分子都是最大整数值导致结果溢出范围为负的情况
// 二要避免先平均再累加时分子太小导致除法结果误差太大
// 因为case里面出现了大数据量累加时导致结果误差累计之后不满足要求

int sum = 0;
double avg = 0;
int cnt = values.size();

int i = 0;
int j = cnt - 1;

values.sort(null);
while (i <= j) {
if (sum <= 0 && values.get(j) >= 0) {
sum = sum + values.get(j);
j--;
} else if (sum >= 0 && values.get(i) <= 0) {
sum = sum + values.get(i);
i++;
} else if (sum == 0) {
sum = values.get(i++);
// sum = values.get(j--);

avg = avg + sum / (double) cnt;

sum = 0;
} else {
avg = avg + sum / (double) cnt;

sum = 0;
}
}

if (sum != 0) {
avg = avg + sum / (double) cnt;
}

list.add(avg);

values.clear();
values.add(node.val);
}

preLevel = map.get(node);
}

// 在不溢出(负数方向溢出和正数方向溢出)的情况下尽可能的累加
// 一要避免先累加再平均时分子太大导致加法结果溢出范围
// 因为case里面出现了分子都是最大整数值导致结果溢出范围为负的情况
// 二要避免先平均再累加时分子太小导致除法结果误差太大
// 因为case里面出现了大数据量累加时导致结果误差累计之后不满足要求

int sum = 0;
double avg = 0;
int cnt = values.size();

int i = 0;
int j = cnt - 1;

values.sort(null);
while (i <= j) {
if (sum <= 0 && values.get(j) >= 0) {
sum = sum + values.get(j);
j--;
} else if (sum >= 0 && values.get(i) <= 0) {
sum = sum + values.get(i);
i++;
} else if (sum == 0) {
sum = values.get(i++);
// sum = values.get(j--);

avg = avg + sum / (double) cnt;

sum = 0;
} else {
avg = avg + sum / (double) cnt;

sum = 0;
}
}

if (sum != 0) {
avg = avg + sum / (double) cnt;
}

list.add(avg);

return list;
}

static class TreeNode {
int val;
TreeNode left;
TreeNode right;

TreeNode() {
}

TreeNode(int val) {
this.val = val;
}

TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}

public static TreeNode genTree(Integer[] array) {
if (array.length == 0) {
return null;
}

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
TreeNode root = new TreeNode(array[0]);
queue.offer(root);

Integer v = null;
int i = 1;
while (i < array.length) {
TreeNode node = queue.poll();

TreeNode left = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;
TreeNode right = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;

// 数组中不包含空节点的子节点的写法(不标准的完全二叉树含空节点的层次遍历)
node.left = left;
node.right = right;
if (left != null) {
queue.offer(left);
}
if (right != null) {
queue.offer(right);
}

// 数组中包含空节点的子节点的写法(标准的完全二叉树含空节点的层次遍历)
// if (node != null) {
// node.left = left;
// node.right = right;
// }
// queue.offer(left);
// queue.offer(right);
}

return root;
}

public static Integer[] toArray(TreeNode root) {
if (root == null) {
return new Integer[0];
}

java.util.LinkedList<Integer> list = new java.util.LinkedList<>();

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
boolean hasValidNode = false;

int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();

if (node != null) {
list.add(node.val);

queue.offer(node.left);
queue.offer(node.right);

if (!hasValidNode) {
hasValidNode = node.left != null || node.right != null;
}
} else {
list.add(null);
}
}

if (!hasValidNode) {
// while (!queue.isEmpty()) {
// queue.poll();
// }

break;
}
}

while (!list.isEmpty() && list.get(list.size() - 1) == null) {
list.remove(list.size() - 1);
}

return list.toArray(new Integer[0]);
}
}
}

class TestMain {

public static void main(String[] args) {
TestUtils.runTestCases(TestCase.class);
}

public static class TestCase {

public static boolean testCase1() {
Integer[] nums = { 3, 9, 20, null, null, 15, 7 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<Double> result = new Solution().averageOfLevels(tree);
Double[] expect = { 3.0, 14.5, 11.0 };

return TestUtils.check(result, expect);
}

public static boolean testCase2() {
Integer[] nums = { 3, 9, 20, 15, 7 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<Double> result = new Solution().averageOfLevels(tree);
Double[] expect = { 3.0, 14.5, 11.0 };

return TestUtils.check(result, expect);
}

public static boolean testCase3() {
Integer[] nums = { 2147483647, 2147483647, 2147483647 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<Double> result = new Solution().averageOfLevels(tree);
Double[] expect = { 2.147483647E9, 2.147483647E9 };

return TestUtils.check(result, expect);
}

public static boolean testCase4() {
Integer[] nums = { 1, 1, 1, 1, 1, 1, 1 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<Double> result = new Solution().averageOfLevels(tree);
Double[] expect = { 1.0, 1.0, 1.0 };

return TestUtils.check(result, expect);
}

public static boolean testCase5() {
Integer[] nums = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2147483647, 2147483647, 2147483647, 2147483643, 2147483645,
2147483646, 2147483646, 2147483624, 2147483646, 2147483647, 2147483646, 2147483647, 2147483647,
2147483631, 2147483647, 2147483647, 2147483647, 2147483647, 2147483631, 2147483647, 2147483647,
2147483647, 2147483647, 2147483646, 2147483646, 2147483614, 2147483646, 2147483647, 2147483646,
2147483647, 2147483646, 2147483647, 2147483646, 2147483647, 2147483646, 2147483647, 2147483646,
2147483647, 2147483646, 2147483647, 2147483646, 2147483647, 2147483646, 2147483647, 2147483646,
2147483647, 2147483646, 2147483647, 2147483644, 2147483644, 2147483647, 2147483647, 2147483644,
2147483647, 2147483647, 2147483644, 2147483647, 2147483647, 2147483644, 2147483647, 2147483647,
2147483644, 2147483647, 2147483647, 2147483644, 2147483647, 2147483647, 2147483644, 2147483647,
2147483647, 2147483644, 2147483647, 2147483647, 2147483644, 2147483647, 2147483647, 2147483644,
2147483647, 2147483647, 2147483644, 2147483647, 2147483647, 2147483644, 2147483647, 2147483647,
2147483644, 2147483647, 2147483647, 2147483644, 2147483647, 2147483647, 2147483644, 2147483647,
2147483647, 2147483642, 2147483647, 2147483647, 2147483647, 2147483636, 2147483647, 2147483647,
2147483647, 2147483647, 2147483647, 2147483647, 2147483636, 2147483647, 2147483647, 2147483647,
2147483647, 2147483647, 2147483647, 2147483636, 2147483647, 2147483647, 2147483647, 2147483647,
2147483647, 2147483647, 2147483636, 2147483647, 2147483647, 2147483647, 2147483647, 2147483647,
2147483647, 2147483636, 2147483647, 2147483647, 2147483647, 2147483647, 2147483647, 2147483647,
2147483636, 2147483647, 2147483647, 2147483647, 2147483647, 2147483647, 2147483647, 2147483636,
2147483647, 2147483647, 2147483647, 2147483647, 2147483647, 2147483647, 2147483636, 2147483647,
2147483647, 2147483647, 2147483647, 2147483647, 2147483647, 2147483636, 2147483647, 2147483647,
2147483647, 2147483647, 2147483647, 2147483647, 2147483636, 2147483647, 2147483647, 2147483647,
2147483647, 2147483647, 2147483647, 2147483636, 2147483647, 2147483647, 2147483647, 2147483647,
2147483647, 2147483647, 2147483636, 2147483647, 2147483647, 2147483647, 2147483647, 2147483647,
2147483647, 2147483636, 2147483647, 2147483647, 2147483647, 2147483647, 2147483647, 2147483647,
2147483642, 2147483642, 2147483647, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642,
2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642,
2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642,
2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642,
2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642,
2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642,
2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642,
2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642,
2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642,
2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642,
2147483642, 2147483642, 2147483647, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642,
2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642,
2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642,
2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642,
2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642,
2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642,
2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642,
2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642,
2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642,
2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642,
2147483642, 2147483642, 2147483647, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642,
2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642,
2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642, 2147483642,
2147483642, 2147483642, 2147483642, 2147483642, 2147483642, -2147483647, -2147483647, -2147483647,
-2147483647, -2147483647, -2147483644, -2147483647, -2147483647, -2147483644, -2147483647,
-2147483647,
-2147483644, -2147483647, -2147483647, -2147483644, -2147483647, -2147483647, -2147483644,
-2147483647,
-2147483647, -2147483644, -2147483647, -2147483647, -2147483644, -2147483647, -2147483647,
-2147483644,
-2147483647, -2147483647, -2147483644, -2147483647, -2147483647, -2147483644, -2147483647,
-2147483647,
-2147483644, -2147483647, -2147483647, -2147483644, -2147483647, -2147483647, -2147483644,
-2147483647,
-2147483647, -2147483644, -2147483647, -2147483647, -2147483644, -2147483647, -2147483647,
-2147483644,
-2147483647, -2147483647, -2147483644, -2147483647, -2147483647, -2147483644, -2147483647,
-2147483647,
-2147483644, -2147483647, -2147483647, -2147483644, -2147483647, -2147483647, -2147483644,
-2147483647,
-2147483647, -2147483644, -2147483647, -2147483647, -2147483644, -2147483647, -2147483647,
-2147483644,
-2147483647, -2147483647, -2147483644, -2147483647, -2147483647, -2147483644, -2147483647,
-2147483647,
-2147483644, -2147483647, -2147483647, -2147483644, -2147483647, -2147483647, -2147483644,
-2147483647,
-2147483647, -2147483644, -2147483647, -2147483647, -2147483644, -2147483647, -2147483647,
-2147483644,
-2147483647, -2147483647, -2147483644, -2147483647, -2147483647, -2147483644, -2147483647,
-2147483647,
-2147483644, -2147483647, -2147483647, -2147483644, -2147483647, -2147483647, -2147483644,
-2147483647,
-2147483647, -2147483644, -2147483647, -2147483647, -2147483644, -2147483647, -2147483647,
-2147483644,
-2147483647, -2147483647, -2147483644, -2147483647, -2147483647, -2147483644, -2147483647,
-2147483647,
-2147483644, -2147483647, -2147483647, -2147483644, -2147483647, -2147483647, -2147483644,
-2147483647,
-2147483647, -2147483644, -2147483647, -2147483647, -2147483644, -2147483647, -2147483647,
-2147483644,
-2147483647, -2147483647, -2147483644, -2147483647, -2147483647, -2147483644, -2147483647,
-2147483647,
-2147483644, -2147483647, -2147483647, -2147483644, -2147483647, -2147483647, -2147483644,
-2147483647,
-2147483647, -2147483644, -2147483647, -2147483647, -2147483644, -2147483647, -2147483647,
-2147483644,
-2147483647, -2147483647, -2147483644, -2147483647, -2147483647, -2147483644, -2147483647,
-2147483647,
-2147483644, -2147483647, -2147483647, -2147483644, -2147483647, -2147483647, -2147483644,
-2147483647,
-2147483647, -2147483638, -2147483642, -2147483642, -2147483642, -2147483642, -2147483642,
-2147483642,
-2147483642, -2147483642, -2147483642, -2147483643, -2147483642, -2147483642, -2147483642,
-2147483642,
-2147483642, -2147483642, -2147483642, -2147483642, -2147483642, -2147483642, -2147483642,
-2147483642,
-2147483642, -2147483642, -2147483642, -2147483643, -2147483642, -2147483642, -2147483642,
-2147483642,
-2147483642, -2147483642, -2147483642, -2147483642, -2147483642, -2147483642, -2147483642,
-2147483642,
-2147483642, -2147483642, -2147483642, -2147483643, -2147483642, -2147483642, -2147483642,
-2147483642,
-2147483642, -2147483642, -2147483642, -2147483642, -2147483642, -2147483642, -2147483642,
-2147483642,
-2147483642, -2147483642, -2147483642, -2147483643, -2147483642, -2147483642, -2147483642,
-2147483642,
-2147483642, -2147483642, -2147483642, -2147483642, -2147483642, -2147483642, -2147483642,
-2147483642,
-2147483642, -2147483642, -2147483642, -2147483643, -2147483642, -2147483642, -2147483642,
-2147483642,
-2147483642, -2147483642, -2147483642, -2147483642, -2147483642, -2147483642, -2147483642,
-2147483642,
-2147483642, -2147483642, -2147483642, -2147483643, -2147483642, -2147483642, -2147483642,
-2147483642,
-2147483598, -2147483647, -2147483647, -2147483647, -2147483647, -2147483645, -2147483647,
-2147483647,
-2147483647, -2147483645, -2147483647, -2147483647, -2147483647, -2147483645, -2147483647,
-2147483647,
-2147483647, -2147483645, -2147483647, -2147483647, -2147483647, -2147483645, -2147483647,
-2147483647,
-2147483647, -2147483645, -2147483647, -2147483647, -2147483647, -2147483645, -2147483647,
-2147483647,
-2147483647, -2147483645, -2147483647, -2147483647, -2147483647, -2147483645, -2147483647,
-2147483647,
-2147483647, -2147483645, -2147483647, -2147483647, -2147483647, -2147483645, -2147483647,
-2147483647,
-2147483647, -2147483647, -2147483647, -2147483647, -2147483647, -2147483647, -2147483647,
-2147483647,
-2147483647, -2147483647, -2147483644, -2147483647, -2147483647, -2147483644, -2147483647,
-2147483647,
-2147483644, -2147483647, -2147483647, -2147483644, -2147483647, -2147483647, -2147483644,
-2147483600,
-2147483646, -2147483646, -2147483646, -2147483646, -2147483646, -2147483646, -2147483646,
-2147483646,
-2147483646, -2147483646, -2147483646, -2147483647, -2147483647, -2147483525, -2147483647,
-2147483647,
-2147483644, -2147483647, -2147483647, -2147483647, -2147483646, -2147483647, -2147483336 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<Double> result = new Solution().averageOfLevels(tree);
Double[] expect = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };

return TestUtils.check(result, expect);
}
}

public static class TestUtils {

public static boolean check(Object result, Object expect) {
result = normalizeObject(result);
expect = normalizeObject(expect);
boolean ok = java.util.Objects.deepEquals(result, expect);
printCheck(toString(result), toString(expect), ok);
return ok;
}

public static boolean check(Object result, String expect) {
boolean ok = java.util.Objects.equals(normalizeString(toString(result)),
normalizeString(toString(expect)));
printCheck(normalizeString(toString(result)), normalizeString(toString(expect)), ok);
return ok;
}

private static Object normalizeObject(Object o) {
if (o instanceof java.util.List) {
java.util.List<?> list = (java.util.List<?>) o;
if (list != null && !list.isEmpty() && list.get(0) instanceof java.util.List) {
o = toArrays(list);
} else {
o = toArray(list);
}
}

return o;
}

private static String toString(Object o) {
if (o instanceof Object[]) {
return java.util.Arrays.deepToString((Object[]) o);
} else if (o instanceof int[]) {
return java.util.Arrays.toString((int[]) o);
} else if (o instanceof double[]) {
return java.util.Arrays.toString((double[]) o);
} else if (o instanceof char[]) {
return java.util.Arrays.toString((char[]) o);
} else {
return java.util.Objects.toString(o);
}
}

private static String normalizeString(String s) {
boolean isArray = (s.startsWith("{") && s.endsWith("}")) || (s.startsWith("[") && s.endsWith("]"));
if (isArray) {
s = s.replace(" ", "")
.replace("'", "")
.replace("\"", "")
.replace("{", "[")
.replace("}", "]");
}

return s;
}

private static void printCheck(String result, String expect, boolean ok) {
// System.out.println();
// System.out.println("--->");

System.out.println("result: " + result);
System.out.println("expect: " + expect);

System.out.println();
if (ok) {
System.out.println("比较结果为: 正确(right)");
} else {
System.out.println("比较结果为: 错误(error)");
}

// System.out.println();
// System.out.println("<---");
}

public static void runTestCases(Class<?> clazz) {
java.lang.reflect.Method[] methods = clazz.getDeclaredMethods();
java.util.Arrays.sort(methods, (o1, o2) -> {
return o1.getName().compareTo(o2.getName());
});
for (java.lang.reflect.Method method : methods) {
if (method.getName().startsWith("test")) {
System.out.println(String.format("--- %s --->", method.getName()));

Object object = null;
try {
object = method.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println(String.format("<--- %s ---", method.getName()));

if (object instanceof Boolean) {
Boolean ok = (Boolean) object;
if (!ok) {
break;
}
} else {
throw new RuntimeException(String.format("测试用例方法%s的返回值需要为布尔类型", method.getName()));
}
}
}
}

public static Object[] toArray(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0];
}

return list.toArray();
}

public static Object[][] toArrays(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0][0];
}

Object[][] arrays = new Object[list.size()][];
for (int i = 0; i < list.size(); i++) {
arrays[i] = toArray(list.get(i));
}

return arrays;
}

@SuppressWarnings("unchecked")
public static <T> T[] genArray(Class<T> clazz, int length) {
return (T[]) java.lang.reflect.Array.newInstance(clazz, length);
}

@SuppressWarnings("unchecked")
public static <T> T[][] genArrays(Class<T> clazz, int rows, int cols) {
T[] array = genArray(clazz, 0);

T[][] arrays = (T[][]) genArray(array.getClass(), rows);
for (int i = 0; i < arrays.length; i++) {
arrays[i] = genArray(clazz, cols);
}

return arrays;
}

public static <T> T[] toArray(java.util.List<T> list, Class<T> clazz) {
if (list == null || list.isEmpty()) {
return genArray(clazz, 0);
}

T[] array = genArray(clazz, list.size());
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}

return array;
}

public static <T> T[][] toArrays(java.util.List<java.util.List<T>> lists, Class<T> clazz) {
if (lists == null || lists.isEmpty()) {
return genArrays(clazz, 0, 0);
}

T[][] arrays = genArrays(clazz, lists.size(), 0);
for (int i = 0; i < lists.size(); i++) {
arrays[i] = toArray(lists.get(i), clazz);
}

return arrays;
}

public static <T> java.util.List<T> toList(T[] array) {
return java.util.Arrays.asList(array);
}

public static <T> java.util.List<java.util.List<T>> toLists(T[][] arrays) {
java.util.List<java.util.List<T>> lists = new java.util.ArrayList<>();
for (T[] array : arrays) {
lists.add(toList(array));
}

return lists;
}
}
}

二叉树的层序遍历

题目描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。



示例 1:

输入:root = [3,9,20,null,null,15,7]
输出:[[3],[9,20],[15,7]]
示例 2:

输入:root = [1]
输出:[[1]]
示例 3:

输入:root = []
输出:[]


提示:

树中节点数目在范围 [0, 2000] 内
-1000 <= Node.val <= 1000

题目解答

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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
import java.util.LinkedList;
import java.util.List;

public class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
if (root == null) {
return new LinkedList<>();
}

List<List<Integer>> lists = new LinkedList<>();

List<TreeNode> nodes = new LinkedList<>();
nodes.add(root);

levelOrder(nodes, lists);

return lists;
}

private void levelOrder(List<TreeNode> nodes, List<List<Integer>> lists) {
if (nodes.isEmpty()) {
return;
}

List<Integer> values = new LinkedList<>();
for (TreeNode node : nodes) {
values.add(node.val);
}
lists.add(values);

List<TreeNode> newNodes = new LinkedList<>();
for (TreeNode node : nodes) {
if (node.left != null) {
newNodes.add(node.left);
}

if (node.right != null) {
newNodes.add(node.right);
}
}

levelOrder(newNodes, lists);
}

static class TreeNode {
int val;
TreeNode left;
TreeNode right;

TreeNode() {
}

TreeNode(int val) {
this.val = val;
}

TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}

public static TreeNode genTree(Integer[] array) {
if (array.length == 0) {
return null;
}

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
TreeNode root = new TreeNode(array[0]);
queue.offer(root);

Integer v = null;
int i = 1;
while (i < array.length) {
TreeNode node = queue.poll();

TreeNode left = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;
TreeNode right = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;

// 数组中不包含空节点的子节点的写法(不标准的完全二叉树含空节点的层次遍历)
node.left = left;
node.right = right;
if (left != null) {
queue.offer(left);
}
if (right != null) {
queue.offer(right);
}

// 数组中包含空节点的子节点的写法(标准的完全二叉树含空节点的层次遍历)
// if (node != null) {
// node.left = left;
// node.right = right;
// }
// queue.offer(left);
// queue.offer(right);
}

return root;
}

public static Integer[] toArray(TreeNode root) {
if (root == null) {
return new Integer[0];
}

java.util.LinkedList<Integer> list = new java.util.LinkedList<>();

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
boolean hasValidNode = false;

int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();

if (node != null) {
list.add(node.val);

queue.offer(node.left);
queue.offer(node.right);

if (!hasValidNode) {
hasValidNode = node.left != null || node.right != null;
}
} else {
list.add(null);
}
}

if (!hasValidNode) {
// while (!queue.isEmpty()) {
// queue.poll();
// }

break;
}
}

while (!list.isEmpty() && list.get(list.size() - 1) == null) {
list.remove(list.size() - 1);
}

return list.toArray(new Integer[0]);
}
}
}

class TestMain {

public static void main(String[] args) {
TestUtils.runTestCases(TestCase.class);
}

public static class TestCase {

public static boolean testCase1() {
Integer[] nums = { 3, 9, 20, null, null, 15, 7 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<List<Integer>> result = new Solution().levelOrder(tree);
Integer[][] expect = { { 3 }, { 9, 20 }, { 15, 7 } };

return TestUtils.check(result, expect);
}

public static boolean testCase2() {
Integer[] nums = { 1 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<List<Integer>> result = new Solution().levelOrder(tree);
Integer[][] expect = { { 1 } };

return TestUtils.check(result, expect);
}

public static boolean testCase3() {
Integer[] nums = {};

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<List<Integer>> result = new Solution().levelOrder(tree);
Integer[][] expect = {};

return TestUtils.check(result, expect);
}
}

public static class TestUtils {

public static boolean check(Object result, Object expect) {
result = normalizeObject(result);
expect = normalizeObject(expect);
boolean ok = java.util.Objects.deepEquals(result, expect);
printCheck(toString(result), toString(expect), ok);
return ok;
}

public static boolean check(Object result, String expect) {
boolean ok = java.util.Objects.equals(normalizeString(toString(result)),
normalizeString(toString(expect)));
printCheck(normalizeString(toString(result)), normalizeString(toString(expect)), ok);
return ok;
}

private static Object normalizeObject(Object o) {
if (o instanceof java.util.List) {
java.util.List<?> list = (java.util.List<?>) o;
if (list != null && !list.isEmpty() && list.get(0) instanceof java.util.List) {
o = toArrays(list);
} else {
o = toArray(list);
}
}

return o;
}

private static String toString(Object o) {
if (o instanceof Object[]) {
return java.util.Arrays.deepToString((Object[]) o);
} else if (o instanceof int[]) {
return java.util.Arrays.toString((int[]) o);
} else if (o instanceof double[]) {
return java.util.Arrays.toString((double[]) o);
} else if (o instanceof char[]) {
return java.util.Arrays.toString((char[]) o);
} else {
return java.util.Objects.toString(o);
}
}

private static String normalizeString(String s) {
boolean isArray = (s.startsWith("{") && s.endsWith("}")) || (s.startsWith("[") && s.endsWith("]"));
if (isArray) {
s = s.replace(" ", "")
.replace("'", "")
.replace("\"", "")
.replace("{", "[")
.replace("}", "]");
}

return s;
}

private static void printCheck(String result, String expect, boolean ok) {
// System.out.println();
// System.out.println("--->");

System.out.println("result: " + result);
System.out.println("expect: " + expect);

System.out.println();
if (ok) {
System.out.println("比较结果为: 正确(right)");
} else {
System.out.println("比较结果为: 错误(error)");
}

// System.out.println();
// System.out.println("<---");
}

public static void runTestCases(Class<?> clazz) {
java.lang.reflect.Method[] methods = clazz.getDeclaredMethods();
java.util.Arrays.sort(methods, (o1, o2) -> {
return o1.getName().compareTo(o2.getName());
});
for (java.lang.reflect.Method method : methods) {
if (method.getName().startsWith("test")) {
System.out.println(String.format("--- %s --->", method.getName()));

Object object = null;
try {
object = method.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println(String.format("<--- %s ---", method.getName()));

if (object instanceof Boolean) {
Boolean ok = (Boolean) object;
if (!ok) {
break;
}
} else {
throw new RuntimeException(String.format("测试用例方法%s的返回值需要为布尔类型", method.getName()));
}
}
}
}

public static Object[] toArray(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0];
}

return list.toArray();
}

public static Object[][] toArrays(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0][0];
}

Object[][] arrays = new Object[list.size()][];
for (int i = 0; i < list.size(); i++) {
arrays[i] = toArray(list.get(i));
}

return arrays;
}

@SuppressWarnings("unchecked")
public static <T> T[] genArray(Class<T> clazz, int length) {
return (T[]) java.lang.reflect.Array.newInstance(clazz, length);
}

@SuppressWarnings("unchecked")
public static <T> T[][] genArrays(Class<T> clazz, int rows, int cols) {
T[] array = genArray(clazz, 0);

T[][] arrays = (T[][]) genArray(array.getClass(), rows);
for (int i = 0; i < arrays.length; i++) {
arrays[i] = genArray(clazz, cols);
}

return arrays;
}

public static <T> T[] toArray(java.util.List<T> list, Class<T> clazz) {
if (list == null || list.isEmpty()) {
return genArray(clazz, 0);
}

T[] array = genArray(clazz, list.size());
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}

return array;
}

public static <T> T[][] toArrays(java.util.List<java.util.List<T>> lists, Class<T> clazz) {
if (lists == null || lists.isEmpty()) {
return genArrays(clazz, 0, 0);
}

T[][] arrays = genArrays(clazz, lists.size(), 0);
for (int i = 0; i < lists.size(); i++) {
arrays[i] = toArray(lists.get(i), clazz);
}

return arrays;
}

public static <T> java.util.List<T> toList(T[] array) {
return java.util.Arrays.asList(array);
}

public static <T> java.util.List<java.util.List<T>> toLists(T[][] arrays) {
java.util.List<java.util.List<T>> lists = new java.util.ArrayList<>();
for (T[] array : arrays) {
lists.add(toList(array));
}

return lists;
}
}
}

进阶解法

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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

public class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
if (root == null) {
return new LinkedList<>();
}

List<List<Integer>> lists = new LinkedList<>();

Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
List<Integer> values = new LinkedList<>();

int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();

if (node.left != null) {
queue.offer(node.left);
}

if (node.right != null) {
queue.offer(node.right);
}

values.add(node.val);
}

lists.add(values);
}

return lists;
}

static class TreeNode {
int val;
TreeNode left;
TreeNode right;

TreeNode() {
}

TreeNode(int val) {
this.val = val;
}

TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}

public static TreeNode genTree(Integer[] array) {
if (array.length == 0) {
return null;
}

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
TreeNode root = new TreeNode(array[0]);
queue.offer(root);

Integer v = null;
int i = 1;
while (i < array.length) {
TreeNode node = queue.poll();

TreeNode left = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;
TreeNode right = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;

// 数组中不包含空节点的子节点的写法(不标准的完全二叉树含空节点的层次遍历)
node.left = left;
node.right = right;
if (left != null) {
queue.offer(left);
}
if (right != null) {
queue.offer(right);
}

// 数组中包含空节点的子节点的写法(标准的完全二叉树含空节点的层次遍历)
// if (node != null) {
// node.left = left;
// node.right = right;
// }
// queue.offer(left);
// queue.offer(right);
}

return root;
}

public static Integer[] toArray(TreeNode root) {
if (root == null) {
return new Integer[0];
}

java.util.LinkedList<Integer> list = new java.util.LinkedList<>();

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
boolean hasValidNode = false;

int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();

if (node != null) {
list.add(node.val);

queue.offer(node.left);
queue.offer(node.right);

if (!hasValidNode) {
hasValidNode = node.left != null || node.right != null;
}
} else {
list.add(null);
}
}

if (!hasValidNode) {
// while (!queue.isEmpty()) {
// queue.poll();
// }

break;
}
}

while (!list.isEmpty() && list.get(list.size() - 1) == null) {
list.remove(list.size() - 1);
}

return list.toArray(new Integer[0]);
}
}
}

class TestMain {

public static void main(String[] args) {
TestUtils.runTestCases(TestCase.class);
}

public static class TestCase {

public static boolean testCase1() {
Integer[] nums = { 3, 9, 20, null, null, 15, 7 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<List<Integer>> result = new Solution().levelOrder(tree);
Integer[][] expect = { { 3 }, { 9, 20 }, { 15, 7 } };

return TestUtils.check(result, expect);
}

public static boolean testCase2() {
Integer[] nums = { 1 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<List<Integer>> result = new Solution().levelOrder(tree);
Integer[][] expect = { { 1 } };

return TestUtils.check(result, expect);
}

public static boolean testCase3() {
Integer[] nums = {};

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<List<Integer>> result = new Solution().levelOrder(tree);
Integer[][] expect = {};

return TestUtils.check(result, expect);
}
}

public static class TestUtils {

public static boolean check(Object result, Object expect) {
result = normalizeObject(result);
expect = normalizeObject(expect);
boolean ok = java.util.Objects.deepEquals(result, expect);
printCheck(toString(result), toString(expect), ok);
return ok;
}

public static boolean check(Object result, String expect) {
boolean ok = java.util.Objects.equals(normalizeString(toString(result)),
normalizeString(toString(expect)));
printCheck(normalizeString(toString(result)), normalizeString(toString(expect)), ok);
return ok;
}

private static Object normalizeObject(Object o) {
if (o instanceof java.util.List) {
java.util.List<?> list = (java.util.List<?>) o;
if (list != null && !list.isEmpty() && list.get(0) instanceof java.util.List) {
o = toArrays(list);
} else {
o = toArray(list);
}
}

return o;
}

private static String toString(Object o) {
if (o instanceof Object[]) {
return java.util.Arrays.deepToString((Object[]) o);
} else if (o instanceof int[]) {
return java.util.Arrays.toString((int[]) o);
} else if (o instanceof double[]) {
return java.util.Arrays.toString((double[]) o);
} else if (o instanceof char[]) {
return java.util.Arrays.toString((char[]) o);
} else {
return java.util.Objects.toString(o);
}
}

private static String normalizeString(String s) {
boolean isArray = (s.startsWith("{") && s.endsWith("}")) || (s.startsWith("[") && s.endsWith("]"));
if (isArray) {
s = s.replace(" ", "")
.replace("'", "")
.replace("\"", "")
.replace("{", "[")
.replace("}", "]");
}

return s;
}

private static void printCheck(String result, String expect, boolean ok) {
// System.out.println();
// System.out.println("--->");

System.out.println("result: " + result);
System.out.println("expect: " + expect);

System.out.println();
if (ok) {
System.out.println("比较结果为: 正确(right)");
} else {
System.out.println("比较结果为: 错误(error)");
}

// System.out.println();
// System.out.println("<---");
}

public static void runTestCases(Class<?> clazz) {
java.lang.reflect.Method[] methods = clazz.getDeclaredMethods();
java.util.Arrays.sort(methods, (o1, o2) -> {
return o1.getName().compareTo(o2.getName());
});
for (java.lang.reflect.Method method : methods) {
if (method.getName().startsWith("test")) {
System.out.println(String.format("--- %s --->", method.getName()));

Object object = null;
try {
object = method.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println(String.format("<--- %s ---", method.getName()));

if (object instanceof Boolean) {
Boolean ok = (Boolean) object;
if (!ok) {
break;
}
} else {
throw new RuntimeException(String.format("测试用例方法%s的返回值需要为布尔类型", method.getName()));
}
}
}
}

public static Object[] toArray(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0];
}

return list.toArray();
}

public static Object[][] toArrays(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0][0];
}

Object[][] arrays = new Object[list.size()][];
for (int i = 0; i < list.size(); i++) {
arrays[i] = toArray(list.get(i));
}

return arrays;
}

@SuppressWarnings("unchecked")
public static <T> T[] genArray(Class<T> clazz, int length) {
return (T[]) java.lang.reflect.Array.newInstance(clazz, length);
}

@SuppressWarnings("unchecked")
public static <T> T[][] genArrays(Class<T> clazz, int rows, int cols) {
T[] array = genArray(clazz, 0);

T[][] arrays = (T[][]) genArray(array.getClass(), rows);
for (int i = 0; i < arrays.length; i++) {
arrays[i] = genArray(clazz, cols);
}

return arrays;
}

public static <T> T[] toArray(java.util.List<T> list, Class<T> clazz) {
if (list == null || list.isEmpty()) {
return genArray(clazz, 0);
}

T[] array = genArray(clazz, list.size());
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}

return array;
}

public static <T> T[][] toArrays(java.util.List<java.util.List<T>> lists, Class<T> clazz) {
if (lists == null || lists.isEmpty()) {
return genArrays(clazz, 0, 0);
}

T[][] arrays = genArrays(clazz, lists.size(), 0);
for (int i = 0; i < lists.size(); i++) {
arrays[i] = toArray(lists.get(i), clazz);
}

return arrays;
}

public static <T> java.util.List<T> toList(T[] array) {
return java.util.Arrays.asList(array);
}

public static <T> java.util.List<java.util.List<T>> toLists(T[][] arrays) {
java.util.List<java.util.List<T>> lists = new java.util.ArrayList<>();
for (T[] array : arrays) {
lists.add(toList(array));
}

return lists;
}
}
}

其他解法

解法1

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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
import java.util.LinkedList;
import java.util.List;

public class Solution {
private List<List<Integer>> lists = new LinkedList<>();

public List<List<Integer>> levelOrder(TreeNode root) {
if (root == null) {
return new LinkedList<>();
}

List<TreeNode> nodes = new LinkedList<>();
nodes.add(root);

levelOrder(nodes);

return lists;
}

private void levelOrder(List<TreeNode> nodes) {
if (nodes.isEmpty()) {
return;
}

List<Integer> values = new LinkedList<>();
List<TreeNode> newNodes = new LinkedList<>();
for (TreeNode node : nodes) {
values.add(node.val);

if (node.left != null) {
newNodes.add(node.left);
}

if (node.right != null) {
newNodes.add(node.right);
}
}

lists.add(values);

levelOrder(newNodes);
}

static class TreeNode {
int val;
TreeNode left;
TreeNode right;

TreeNode() {
}

TreeNode(int val) {
this.val = val;
}

TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}

public static TreeNode genTree(Integer[] array) {
if (array.length == 0) {
return null;
}

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
TreeNode root = new TreeNode(array[0]);
queue.offer(root);

Integer v = null;
int i = 1;
while (i < array.length) {
TreeNode node = queue.poll();

TreeNode left = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;
TreeNode right = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;

// 数组中不包含空节点的子节点的写法(不标准的完全二叉树含空节点的层次遍历)
node.left = left;
node.right = right;
if (left != null) {
queue.offer(left);
}
if (right != null) {
queue.offer(right);
}

// 数组中包含空节点的子节点的写法(标准的完全二叉树含空节点的层次遍历)
// if (node != null) {
// node.left = left;
// node.right = right;
// }
// queue.offer(left);
// queue.offer(right);
}

return root;
}

public static Integer[] toArray(TreeNode root) {
if (root == null) {
return new Integer[0];
}

java.util.LinkedList<Integer> list = new java.util.LinkedList<>();

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
boolean hasValidNode = false;

int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();

if (node != null) {
list.add(node.val);

queue.offer(node.left);
queue.offer(node.right);

if (!hasValidNode) {
hasValidNode = node.left != null || node.right != null;
}
} else {
list.add(null);
}
}

if (!hasValidNode) {
// while (!queue.isEmpty()) {
// queue.poll();
// }

break;
}
}

while (!list.isEmpty() && list.get(list.size() - 1) == null) {
list.remove(list.size() - 1);
}

return list.toArray(new Integer[0]);
}
}
}

class TestMain {

public static void main(String[] args) {
TestUtils.runTestCases(TestCase.class);
}

public static class TestCase {

public static boolean testCase1() {
Integer[] nums = { 3, 9, 20, null, null, 15, 7 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<List<Integer>> result = new Solution().levelOrder(tree);
Integer[][] expect = { { 3 }, { 9, 20 }, { 15, 7 } };

return TestUtils.check(result, expect);
}

public static boolean testCase2() {
Integer[] nums = { 1 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<List<Integer>> result = new Solution().levelOrder(tree);
Integer[][] expect = { { 1 } };

return TestUtils.check(result, expect);
}

public static boolean testCase3() {
Integer[] nums = {};

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<List<Integer>> result = new Solution().levelOrder(tree);
Integer[][] expect = {};

return TestUtils.check(result, expect);
}
}

public static class TestUtils {

public static boolean check(Object result, Object expect) {
result = normalizeObject(result);
expect = normalizeObject(expect);
boolean ok = java.util.Objects.deepEquals(result, expect);
printCheck(toString(result), toString(expect), ok);
return ok;
}

public static boolean check(Object result, String expect) {
boolean ok = java.util.Objects.equals(normalizeString(toString(result)),
normalizeString(toString(expect)));
printCheck(normalizeString(toString(result)), normalizeString(toString(expect)), ok);
return ok;
}

private static Object normalizeObject(Object o) {
if (o instanceof java.util.List) {
java.util.List<?> list = (java.util.List<?>) o;
if (list != null && !list.isEmpty() && list.get(0) instanceof java.util.List) {
o = toArrays(list);
} else {
o = toArray(list);
}
}

return o;
}

private static String toString(Object o) {
if (o instanceof Object[]) {
return java.util.Arrays.deepToString((Object[]) o);
} else if (o instanceof int[]) {
return java.util.Arrays.toString((int[]) o);
} else if (o instanceof double[]) {
return java.util.Arrays.toString((double[]) o);
} else if (o instanceof char[]) {
return java.util.Arrays.toString((char[]) o);
} else {
return java.util.Objects.toString(o);
}
}

private static String normalizeString(String s) {
boolean isArray = (s.startsWith("{") && s.endsWith("}")) || (s.startsWith("[") && s.endsWith("]"));
if (isArray) {
s = s.replace(" ", "")
.replace("'", "")
.replace("\"", "")
.replace("{", "[")
.replace("}", "]");
}

return s;
}

private static void printCheck(String result, String expect, boolean ok) {
// System.out.println();
// System.out.println("--->");

System.out.println("result: " + result);
System.out.println("expect: " + expect);

System.out.println();
if (ok) {
System.out.println("比较结果为: 正确(right)");
} else {
System.out.println("比较结果为: 错误(error)");
}

// System.out.println();
// System.out.println("<---");
}

public static void runTestCases(Class<?> clazz) {
java.lang.reflect.Method[] methods = clazz.getDeclaredMethods();
java.util.Arrays.sort(methods, (o1, o2) -> {
return o1.getName().compareTo(o2.getName());
});
for (java.lang.reflect.Method method : methods) {
if (method.getName().startsWith("test")) {
System.out.println(String.format("--- %s --->", method.getName()));

Object object = null;
try {
object = method.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println(String.format("<--- %s ---", method.getName()));

if (object instanceof Boolean) {
Boolean ok = (Boolean) object;
if (!ok) {
break;
}
} else {
throw new RuntimeException(String.format("测试用例方法%s的返回值需要为布尔类型", method.getName()));
}
}
}
}

public static Object[] toArray(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0];
}

return list.toArray();
}

public static Object[][] toArrays(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0][0];
}

Object[][] arrays = new Object[list.size()][];
for (int i = 0; i < list.size(); i++) {
arrays[i] = toArray(list.get(i));
}

return arrays;
}

@SuppressWarnings("unchecked")
public static <T> T[] genArray(Class<T> clazz, int length) {
return (T[]) java.lang.reflect.Array.newInstance(clazz, length);
}

@SuppressWarnings("unchecked")
public static <T> T[][] genArrays(Class<T> clazz, int rows, int cols) {
T[] array = genArray(clazz, 0);

T[][] arrays = (T[][]) genArray(array.getClass(), rows);
for (int i = 0; i < arrays.length; i++) {
arrays[i] = genArray(clazz, cols);
}

return arrays;
}

public static <T> T[] toArray(java.util.List<T> list, Class<T> clazz) {
if (list == null || list.isEmpty()) {
return genArray(clazz, 0);
}

T[] array = genArray(clazz, list.size());
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}

return array;
}

public static <T> T[][] toArrays(java.util.List<java.util.List<T>> lists, Class<T> clazz) {
if (lists == null || lists.isEmpty()) {
return genArrays(clazz, 0, 0);
}

T[][] arrays = genArrays(clazz, lists.size(), 0);
for (int i = 0; i < lists.size(); i++) {
arrays[i] = toArray(lists.get(i), clazz);
}

return arrays;
}

public static <T> java.util.List<T> toList(T[] array) {
return java.util.Arrays.asList(array);
}

public static <T> java.util.List<java.util.List<T>> toLists(T[][] arrays) {
java.util.List<java.util.List<T>> lists = new java.util.ArrayList<>();
for (T[] array : arrays) {
lists.add(toList(array));
}

return lists;
}
}
}

解法2

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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
import java.util.LinkedList;
import java.util.List;

public class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
if (root == null) {
return new LinkedList<>();
}

List<List<Integer>> lists = new LinkedList<>();

List<TreeNode> nodes = new LinkedList<>();
nodes.add(root);

while (!nodes.isEmpty()) {
List<Integer> values = new LinkedList<>();
List<TreeNode> newNodes = new LinkedList<>();
for (TreeNode node : nodes) {
values.add(node.val);

if (node.left != null) {
newNodes.add(node.left);
}

if (node.right != null) {
newNodes.add(node.right);
}
}

lists.add(values);

nodes = newNodes;
}

return lists;
}

static class TreeNode {
int val;
TreeNode left;
TreeNode right;

TreeNode() {
}

TreeNode(int val) {
this.val = val;
}

TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}

public static TreeNode genTree(Integer[] array) {
if (array.length == 0) {
return null;
}

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
TreeNode root = new TreeNode(array[0]);
queue.offer(root);

Integer v = null;
int i = 1;
while (i < array.length) {
TreeNode node = queue.poll();

TreeNode left = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;
TreeNode right = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;

// 数组中不包含空节点的子节点的写法(不标准的完全二叉树含空节点的层次遍历)
node.left = left;
node.right = right;
if (left != null) {
queue.offer(left);
}
if (right != null) {
queue.offer(right);
}

// 数组中包含空节点的子节点的写法(标准的完全二叉树含空节点的层次遍历)
// if (node != null) {
// node.left = left;
// node.right = right;
// }
// queue.offer(left);
// queue.offer(right);
}

return root;
}

public static Integer[] toArray(TreeNode root) {
if (root == null) {
return new Integer[0];
}

java.util.LinkedList<Integer> list = new java.util.LinkedList<>();

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
boolean hasValidNode = false;

int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();

if (node != null) {
list.add(node.val);

queue.offer(node.left);
queue.offer(node.right);

if (!hasValidNode) {
hasValidNode = node.left != null || node.right != null;
}
} else {
list.add(null);
}
}

if (!hasValidNode) {
// while (!queue.isEmpty()) {
// queue.poll();
// }

break;
}
}

while (!list.isEmpty() && list.get(list.size() - 1) == null) {
list.remove(list.size() - 1);
}

return list.toArray(new Integer[0]);
}
}
}

class TestMain {

public static void main(String[] args) {
TestUtils.runTestCases(TestCase.class);
}

public static class TestCase {

public static boolean testCase1() {
Integer[] nums = { 3, 9, 20, null, null, 15, 7 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<List<Integer>> result = new Solution().levelOrder(tree);
Integer[][] expect = { { 3 }, { 9, 20 }, { 15, 7 } };

return TestUtils.check(result, expect);
}

public static boolean testCase2() {
Integer[] nums = { 1 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<List<Integer>> result = new Solution().levelOrder(tree);
Integer[][] expect = { { 1 } };

return TestUtils.check(result, expect);
}

public static boolean testCase3() {
Integer[] nums = {};

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<List<Integer>> result = new Solution().levelOrder(tree);
Integer[][] expect = {};

return TestUtils.check(result, expect);
}
}

public static class TestUtils {

public static boolean check(Object result, Object expect) {
result = normalizeObject(result);
expect = normalizeObject(expect);
boolean ok = java.util.Objects.deepEquals(result, expect);
printCheck(toString(result), toString(expect), ok);
return ok;
}

public static boolean check(Object result, String expect) {
boolean ok = java.util.Objects.equals(normalizeString(toString(result)),
normalizeString(toString(expect)));
printCheck(normalizeString(toString(result)), normalizeString(toString(expect)), ok);
return ok;
}

private static Object normalizeObject(Object o) {
if (o instanceof java.util.List) {
java.util.List<?> list = (java.util.List<?>) o;
if (list != null && !list.isEmpty() && list.get(0) instanceof java.util.List) {
o = toArrays(list);
} else {
o = toArray(list);
}
}

return o;
}

private static String toString(Object o) {
if (o instanceof Object[]) {
return java.util.Arrays.deepToString((Object[]) o);
} else if (o instanceof int[]) {
return java.util.Arrays.toString((int[]) o);
} else if (o instanceof double[]) {
return java.util.Arrays.toString((double[]) o);
} else if (o instanceof char[]) {
return java.util.Arrays.toString((char[]) o);
} else {
return java.util.Objects.toString(o);
}
}

private static String normalizeString(String s) {
boolean isArray = (s.startsWith("{") && s.endsWith("}")) || (s.startsWith("[") && s.endsWith("]"));
if (isArray) {
s = s.replace(" ", "")
.replace("'", "")
.replace("\"", "")
.replace("{", "[")
.replace("}", "]");
}

return s;
}

private static void printCheck(String result, String expect, boolean ok) {
// System.out.println();
// System.out.println("--->");

System.out.println("result: " + result);
System.out.println("expect: " + expect);

System.out.println();
if (ok) {
System.out.println("比较结果为: 正确(right)");
} else {
System.out.println("比较结果为: 错误(error)");
}

// System.out.println();
// System.out.println("<---");
}

public static void runTestCases(Class<?> clazz) {
java.lang.reflect.Method[] methods = clazz.getDeclaredMethods();
java.util.Arrays.sort(methods, (o1, o2) -> {
return o1.getName().compareTo(o2.getName());
});
for (java.lang.reflect.Method method : methods) {
if (method.getName().startsWith("test")) {
System.out.println(String.format("--- %s --->", method.getName()));

Object object = null;
try {
object = method.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println(String.format("<--- %s ---", method.getName()));

if (object instanceof Boolean) {
Boolean ok = (Boolean) object;
if (!ok) {
break;
}
} else {
throw new RuntimeException(String.format("测试用例方法%s的返回值需要为布尔类型", method.getName()));
}
}
}
}

public static Object[] toArray(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0];
}

return list.toArray();
}

public static Object[][] toArrays(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0][0];
}

Object[][] arrays = new Object[list.size()][];
for (int i = 0; i < list.size(); i++) {
arrays[i] = toArray(list.get(i));
}

return arrays;
}

@SuppressWarnings("unchecked")
public static <T> T[] genArray(Class<T> clazz, int length) {
return (T[]) java.lang.reflect.Array.newInstance(clazz, length);
}

@SuppressWarnings("unchecked")
public static <T> T[][] genArrays(Class<T> clazz, int rows, int cols) {
T[] array = genArray(clazz, 0);

T[][] arrays = (T[][]) genArray(array.getClass(), rows);
for (int i = 0; i < arrays.length; i++) {
arrays[i] = genArray(clazz, cols);
}

return arrays;
}

public static <T> T[] toArray(java.util.List<T> list, Class<T> clazz) {
if (list == null || list.isEmpty()) {
return genArray(clazz, 0);
}

T[] array = genArray(clazz, list.size());
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}

return array;
}

public static <T> T[][] toArrays(java.util.List<java.util.List<T>> lists, Class<T> clazz) {
if (lists == null || lists.isEmpty()) {
return genArrays(clazz, 0, 0);
}

T[][] arrays = genArrays(clazz, lists.size(), 0);
for (int i = 0; i < lists.size(); i++) {
arrays[i] = toArray(lists.get(i), clazz);
}

return arrays;
}

public static <T> java.util.List<T> toList(T[] array) {
return java.util.Arrays.asList(array);
}

public static <T> java.util.List<java.util.List<T>> toLists(T[][] arrays) {
java.util.List<java.util.List<T>> lists = new java.util.ArrayList<>();
for (T[] array : arrays) {
lists.add(toList(array));
}

return lists;
}
}
}

解法3

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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;

public class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
if (root == null) {
return new LinkedList<>();
}

List<List<Integer>> lists = new LinkedList<>();

int preLevel = 1;
List<Integer> values = new LinkedList<>();

Map<TreeNode, Integer> map = new HashMap<>(); // 存储每个结点的层次
map.put(root, 1);

Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
TreeNode node = queue.poll();

if (node.left != null) {
queue.offer(node.left);

map.put(node.left, map.get(node) + 1);
}

if (node.right != null) {
queue.offer(node.right);

map.put(node.right, map.get(node) + 1);
}

if (map.get(node) == preLevel) {
values.add(node.val);
} else {
lists.add(values);

values = new ArrayList<>();
values.add(node.val);
}

preLevel = map.get(node);
}

lists.add(values);

return lists;
}

static class TreeNode {
int val;
TreeNode left;
TreeNode right;

TreeNode() {
}

TreeNode(int val) {
this.val = val;
}

TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}

public static TreeNode genTree(Integer[] array) {
if (array.length == 0) {
return null;
}

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
TreeNode root = new TreeNode(array[0]);
queue.offer(root);

Integer v = null;
int i = 1;
while (i < array.length) {
TreeNode node = queue.poll();

TreeNode left = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;
TreeNode right = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;

// 数组中不包含空节点的子节点的写法(不标准的完全二叉树含空节点的层次遍历)
node.left = left;
node.right = right;
if (left != null) {
queue.offer(left);
}
if (right != null) {
queue.offer(right);
}

// 数组中包含空节点的子节点的写法(标准的完全二叉树含空节点的层次遍历)
// if (node != null) {
// node.left = left;
// node.right = right;
// }
// queue.offer(left);
// queue.offer(right);
}

return root;
}

public static Integer[] toArray(TreeNode root) {
if (root == null) {
return new Integer[0];
}

java.util.LinkedList<Integer> list = new java.util.LinkedList<>();

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
boolean hasValidNode = false;

int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();

if (node != null) {
list.add(node.val);

queue.offer(node.left);
queue.offer(node.right);

if (!hasValidNode) {
hasValidNode = node.left != null || node.right != null;
}
} else {
list.add(null);
}
}

if (!hasValidNode) {
// while (!queue.isEmpty()) {
// queue.poll();
// }

break;
}
}

while (!list.isEmpty() && list.get(list.size() - 1) == null) {
list.remove(list.size() - 1);
}

return list.toArray(new Integer[0]);
}
}
}

class TestMain {

public static void main(String[] args) {
TestUtils.runTestCases(TestCase.class);
}

public static class TestCase {

public static boolean testCase1() {
Integer[] nums = { 3, 9, 20, null, null, 15, 7 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<List<Integer>> result = new Solution().levelOrder(tree);
Integer[][] expect = { { 3 }, { 9, 20 }, { 15, 7 } };

return TestUtils.check(result, expect);
}

public static boolean testCase2() {
Integer[] nums = { 1 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<List<Integer>> result = new Solution().levelOrder(tree);
Integer[][] expect = { { 1 } };

return TestUtils.check(result, expect);
}

public static boolean testCase3() {
Integer[] nums = {};

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<List<Integer>> result = new Solution().levelOrder(tree);
Integer[][] expect = {};

return TestUtils.check(result, expect);
}
}

public static class TestUtils {

public static boolean check(Object result, Object expect) {
result = normalizeObject(result);
expect = normalizeObject(expect);
boolean ok = java.util.Objects.deepEquals(result, expect);
printCheck(toString(result), toString(expect), ok);
return ok;
}

public static boolean check(Object result, String expect) {
boolean ok = java.util.Objects.equals(normalizeString(toString(result)),
normalizeString(toString(expect)));
printCheck(normalizeString(toString(result)), normalizeString(toString(expect)), ok);
return ok;
}

private static Object normalizeObject(Object o) {
if (o instanceof java.util.List) {
java.util.List<?> list = (java.util.List<?>) o;
if (list != null && !list.isEmpty() && list.get(0) instanceof java.util.List) {
o = toArrays(list);
} else {
o = toArray(list);
}
}

return o;
}

private static String toString(Object o) {
if (o instanceof Object[]) {
return java.util.Arrays.deepToString((Object[]) o);
} else if (o instanceof int[]) {
return java.util.Arrays.toString((int[]) o);
} else if (o instanceof double[]) {
return java.util.Arrays.toString((double[]) o);
} else if (o instanceof char[]) {
return java.util.Arrays.toString((char[]) o);
} else {
return java.util.Objects.toString(o);
}
}

private static String normalizeString(String s) {
boolean isArray = (s.startsWith("{") && s.endsWith("}")) || (s.startsWith("[") && s.endsWith("]"));
if (isArray) {
s = s.replace(" ", "")
.replace("'", "")
.replace("\"", "")
.replace("{", "[")
.replace("}", "]");
}

return s;
}

private static void printCheck(String result, String expect, boolean ok) {
// System.out.println();
// System.out.println("--->");

System.out.println("result: " + result);
System.out.println("expect: " + expect);

System.out.println();
if (ok) {
System.out.println("比较结果为: 正确(right)");
} else {
System.out.println("比较结果为: 错误(error)");
}

// System.out.println();
// System.out.println("<---");
}

public static void runTestCases(Class<?> clazz) {
java.lang.reflect.Method[] methods = clazz.getDeclaredMethods();
java.util.Arrays.sort(methods, (o1, o2) -> {
return o1.getName().compareTo(o2.getName());
});
for (java.lang.reflect.Method method : methods) {
if (method.getName().startsWith("test")) {
System.out.println(String.format("--- %s --->", method.getName()));

Object object = null;
try {
object = method.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println(String.format("<--- %s ---", method.getName()));

if (object instanceof Boolean) {
Boolean ok = (Boolean) object;
if (!ok) {
break;
}
} else {
throw new RuntimeException(String.format("测试用例方法%s的返回值需要为布尔类型", method.getName()));
}
}
}
}

public static Object[] toArray(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0];
}

return list.toArray();
}

public static Object[][] toArrays(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0][0];
}

Object[][] arrays = new Object[list.size()][];
for (int i = 0; i < list.size(); i++) {
arrays[i] = toArray(list.get(i));
}

return arrays;
}

@SuppressWarnings("unchecked")
public static <T> T[] genArray(Class<T> clazz, int length) {
return (T[]) java.lang.reflect.Array.newInstance(clazz, length);
}

@SuppressWarnings("unchecked")
public static <T> T[][] genArrays(Class<T> clazz, int rows, int cols) {
T[] array = genArray(clazz, 0);

T[][] arrays = (T[][]) genArray(array.getClass(), rows);
for (int i = 0; i < arrays.length; i++) {
arrays[i] = genArray(clazz, cols);
}

return arrays;
}

public static <T> T[] toArray(java.util.List<T> list, Class<T> clazz) {
if (list == null || list.isEmpty()) {
return genArray(clazz, 0);
}

T[] array = genArray(clazz, list.size());
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}

return array;
}

public static <T> T[][] toArrays(java.util.List<java.util.List<T>> lists, Class<T> clazz) {
if (lists == null || lists.isEmpty()) {
return genArrays(clazz, 0, 0);
}

T[][] arrays = genArrays(clazz, lists.size(), 0);
for (int i = 0; i < lists.size(); i++) {
arrays[i] = toArray(lists.get(i), clazz);
}

return arrays;
}

public static <T> java.util.List<T> toList(T[] array) {
return java.util.Arrays.asList(array);
}

public static <T> java.util.List<java.util.List<T>> toLists(T[][] arrays) {
java.util.List<java.util.List<T>> lists = new java.util.ArrayList<>();
for (T[] array : arrays) {
lists.add(toList(array));
}

return lists;
}
}
}

二叉树的前序遍历

题目描述

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
给你二叉树的根节点 root ,返回它节点值的 前序 遍历。



示例 1:

输入:root = [1,null,2,3]
输出:[1,2,3]
示例 2:

输入:root = []
输出:[]
示例 3:

输入:root = [1]
输出:[1]
示例 4:

输入:root = [1,2]
输出:[1,2]
示例 5:

输入:root = [1,null,2]
输出:[1,2]


提示:

树中节点数目在范围 [0, 100] 内
-100 <= Node.val <= 100


进阶:递归算法很简单,你可以通过迭代算法完成吗?

题目解答

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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
import java.util.LinkedList;
import java.util.List;

public class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
if (root == null) {
return new LinkedList<>();
}

List<Integer> list = new LinkedList<>();

list.add(root.val);
list.addAll(preorderTraversal(root.left));
list.addAll(preorderTraversal(root.right));

return list;
}

static class TreeNode {
int val;
TreeNode left;
TreeNode right;

TreeNode() {
}

TreeNode(int val) {
this.val = val;
}

TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}

public static TreeNode genTree(Integer[] array) {
if (array.length == 0) {
return null;
}

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
TreeNode root = new TreeNode(array[0]);
queue.offer(root);

Integer v = null;
int i = 1;
while (i < array.length) {
TreeNode node = queue.poll();

TreeNode left = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;
TreeNode right = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;

// 数组中不包含空节点的子节点的写法(不标准的完全二叉树含空节点的层次遍历)
node.left = left;
node.right = right;
if (left != null) {
queue.offer(left);
}
if (right != null) {
queue.offer(right);
}

// 数组中包含空节点的子节点的写法(标准的完全二叉树含空节点的层次遍历)
// if (node != null) {
// node.left = left;
// node.right = right;
// }
// queue.offer(left);
// queue.offer(right);
}

return root;
}

public static Integer[] toArray(TreeNode root) {
if (root == null) {
return new Integer[0];
}

java.util.LinkedList<Integer> list = new java.util.LinkedList<>();

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
boolean hasValidNode = false;

int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();

if (node != null) {
list.add(node.val);

queue.offer(node.left);
queue.offer(node.right);

if (!hasValidNode) {
hasValidNode = node.left != null || node.right != null;
}
} else {
list.add(null);
}
}

if (!hasValidNode) {
// while (!queue.isEmpty()) {
// queue.poll();
// }

break;
}
}

while (!list.isEmpty() && list.get(list.size() - 1) == null) {
list.remove(list.size() - 1);
}

return list.toArray(new Integer[0]);
}
}
}

class TestMain {

public static void main(String[] args) {
TestUtils.runTestCases(TestCase.class);
}

public static class TestCase {

public static boolean testCase1() {
Integer[] nums = { 1, null, 2, 3 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<Integer> result = new Solution().preorderTraversal(tree);
Integer[] expect = { 1, 2, 3 };

return TestUtils.check(result, expect);
}

public static boolean testCase2() {
Integer[] nums = {};

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<Integer> result = new Solution().preorderTraversal(tree);
Integer[] expect = {};

return TestUtils.check(result, expect);
}

public static boolean testCase3() {
Integer[] nums = { 1 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<Integer> result = new Solution().preorderTraversal(tree);
Integer[] expect = { 1 };

return TestUtils.check(result, expect);
}

}

public static class TestUtils {

public static boolean check(Object result, Object expect) {
result = normalizeObject(result);
expect = normalizeObject(expect);
boolean ok = java.util.Objects.deepEquals(result, expect);
printCheck(toString(result), toString(expect), ok);
return ok;
}

public static boolean check(Object result, String expect) {
boolean ok = java.util.Objects.equals(normalizeString(toString(result)),
normalizeString(toString(expect)));
printCheck(normalizeString(toString(result)), normalizeString(toString(expect)), ok);
return ok;
}

private static Object normalizeObject(Object o) {
if (o instanceof java.util.List) {
java.util.List<?> list = (java.util.List<?>) o;
if (list != null && !list.isEmpty() && list.get(0) instanceof java.util.List) {
o = toArrays(list);
} else {
o = toArray(list);
}
}

return o;
}

private static String toString(Object o) {
if (o instanceof Object[]) {
return java.util.Arrays.deepToString((Object[]) o);
} else if (o instanceof int[]) {
return java.util.Arrays.toString((int[]) o);
} else if (o instanceof double[]) {
return java.util.Arrays.toString((double[]) o);
} else if (o instanceof char[]) {
return java.util.Arrays.toString((char[]) o);
} else {
return java.util.Objects.toString(o);
}
}

private static String normalizeString(String s) {
boolean isArray = (s.startsWith("{") && s.endsWith("}")) || (s.startsWith("[") && s.endsWith("]"));
if (isArray) {
s = s.replace(" ", "")
.replace("'", "")
.replace("\"", "")
.replace("{", "[")
.replace("}", "]");
}

return s;
}

private static void printCheck(String result, String expect, boolean ok) {
// System.out.println();
// System.out.println("--->");

System.out.println("result: " + result);
System.out.println("expect: " + expect);

System.out.println();
if (ok) {
System.out.println("比较结果为: 正确(right)");
} else {
System.out.println("比较结果为: 错误(error)");
}

// System.out.println();
// System.out.println("<---");
}

public static void runTestCases(Class<?> clazz) {
java.lang.reflect.Method[] methods = clazz.getDeclaredMethods();
java.util.Arrays.sort(methods, (o1, o2) -> {
return o1.getName().compareTo(o2.getName());
});
for (java.lang.reflect.Method method : methods) {
if (method.getName().startsWith("test")) {
System.out.println(String.format("--- %s --->", method.getName()));

Object object = null;
try {
object = method.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println(String.format("<--- %s ---", method.getName()));

if (object instanceof Boolean) {
Boolean ok = (Boolean) object;
if (!ok) {
break;
}
} else {
throw new RuntimeException(String.format("测试用例方法%s的返回值需要为布尔类型", method.getName()));
}
}
}
}

public static Object[] toArray(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0];
}

return list.toArray();
}

public static Object[][] toArrays(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0][0];
}

Object[][] arrays = new Object[list.size()][];
for (int i = 0; i < list.size(); i++) {
arrays[i] = toArray(list.get(i));
}

return arrays;
}

@SuppressWarnings("unchecked")
public static <T> T[] genArray(Class<T> clazz, int length) {
return (T[]) java.lang.reflect.Array.newInstance(clazz, length);
}

@SuppressWarnings("unchecked")
public static <T> T[][] genArrays(Class<T> clazz, int rows, int cols) {
T[] array = genArray(clazz, 0);

T[][] arrays = (T[][]) genArray(array.getClass(), rows);
for (int i = 0; i < arrays.length; i++) {
arrays[i] = genArray(clazz, cols);
}

return arrays;
}

public static <T> T[] toArray(java.util.List<T> list, Class<T> clazz) {
if (list == null || list.isEmpty()) {
return genArray(clazz, 0);
}

T[] array = genArray(clazz, list.size());
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}

return array;
}

public static <T> T[][] toArrays(java.util.List<java.util.List<T>> lists, Class<T> clazz) {
if (lists == null || lists.isEmpty()) {
return genArrays(clazz, 0, 0);
}

T[][] arrays = genArrays(clazz, lists.size(), 0);
for (int i = 0; i < lists.size(); i++) {
arrays[i] = toArray(lists.get(i), clazz);
}

return arrays;
}

public static <T> java.util.List<T> toList(T[] array) {
return java.util.Arrays.asList(array);
}

public static <T> java.util.List<java.util.List<T>> toLists(T[][] arrays) {
java.util.List<java.util.List<T>> lists = new java.util.ArrayList<>();
for (T[] array : arrays) {
lists.add(toList(array));
}

return lists;
}
}
}

进阶解法

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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
import java.util.Deque;
import java.util.LinkedList;
import java.util.List;

public class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
if (root == null) {
return new LinkedList<>();
}

List<Integer> list = new LinkedList<>();

Deque<TreeNode> stack = new LinkedList<>();

TreeNode p = root;
while (p != null || !stack.isEmpty()) {
if (p != null) {
list.add(p.val);

stack.push(p);

p = p.left;
} else {
p = stack.pop();

p = p.right;
}
}

return list;
}

static class TreeNode {
int val;
TreeNode left;
TreeNode right;

TreeNode() {
}

TreeNode(int val) {
this.val = val;
}

TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}

public static TreeNode genTree(Integer[] array) {
if (array.length == 0) {
return null;
}

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
TreeNode root = new TreeNode(array[0]);
queue.offer(root);

Integer v = null;
int i = 1;
while (i < array.length) {
TreeNode node = queue.poll();

TreeNode left = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;
TreeNode right = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;

// 数组中不包含空节点的子节点的写法(不标准的完全二叉树含空节点的层次遍历)
node.left = left;
node.right = right;
if (left != null) {
queue.offer(left);
}
if (right != null) {
queue.offer(right);
}

// 数组中包含空节点的子节点的写法(标准的完全二叉树含空节点的层次遍历)
// if (node != null) {
// node.left = left;
// node.right = right;
// }
// queue.offer(left);
// queue.offer(right);
}

return root;
}

public static Integer[] toArray(TreeNode root) {
if (root == null) {
return new Integer[0];
}

java.util.LinkedList<Integer> list = new java.util.LinkedList<>();

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
boolean hasValidNode = false;

int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();

if (node != null) {
list.add(node.val);

queue.offer(node.left);
queue.offer(node.right);

if (!hasValidNode) {
hasValidNode = node.left != null || node.right != null;
}
} else {
list.add(null);
}
}

if (!hasValidNode) {
// while (!queue.isEmpty()) {
// queue.poll();
// }

break;
}
}

while (!list.isEmpty() && list.get(list.size() - 1) == null) {
list.remove(list.size() - 1);
}

return list.toArray(new Integer[0]);
}
}
}

class TestMain {

public static void main(String[] args) {
TestUtils.runTestCases(TestCase.class);
}

public static class TestCase {

public static boolean testCase1() {
Integer[] nums = { 1, null, 2, 3 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<Integer> result = new Solution().preorderTraversal(tree);
Integer[] expect = { 1, 2, 3 };

return TestUtils.check(result, expect);
}

public static boolean testCase2() {
Integer[] nums = {};

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<Integer> result = new Solution().preorderTraversal(tree);
Integer[] expect = {};

return TestUtils.check(result, expect);
}

public static boolean testCase3() {
Integer[] nums = { 1 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<Integer> result = new Solution().preorderTraversal(tree);
Integer[] expect = { 1 };

return TestUtils.check(result, expect);
}

}

public static class TestUtils {

public static boolean check(Object result, Object expect) {
result = normalizeObject(result);
expect = normalizeObject(expect);
boolean ok = java.util.Objects.deepEquals(result, expect);
printCheck(toString(result), toString(expect), ok);
return ok;
}

public static boolean check(Object result, String expect) {
boolean ok = java.util.Objects.equals(normalizeString(toString(result)),
normalizeString(toString(expect)));
printCheck(normalizeString(toString(result)), normalizeString(toString(expect)), ok);
return ok;
}

private static Object normalizeObject(Object o) {
if (o instanceof java.util.List) {
java.util.List<?> list = (java.util.List<?>) o;
if (list != null && !list.isEmpty() && list.get(0) instanceof java.util.List) {
o = toArrays(list);
} else {
o = toArray(list);
}
}

return o;
}

private static String toString(Object o) {
if (o instanceof Object[]) {
return java.util.Arrays.deepToString((Object[]) o);
} else if (o instanceof int[]) {
return java.util.Arrays.toString((int[]) o);
} else if (o instanceof double[]) {
return java.util.Arrays.toString((double[]) o);
} else if (o instanceof char[]) {
return java.util.Arrays.toString((char[]) o);
} else {
return java.util.Objects.toString(o);
}
}

private static String normalizeString(String s) {
boolean isArray = (s.startsWith("{") && s.endsWith("}")) || (s.startsWith("[") && s.endsWith("]"));
if (isArray) {
s = s.replace(" ", "")
.replace("'", "")
.replace("\"", "")
.replace("{", "[")
.replace("}", "]");
}

return s;
}

private static void printCheck(String result, String expect, boolean ok) {
// System.out.println();
// System.out.println("--->");

System.out.println("result: " + result);
System.out.println("expect: " + expect);

System.out.println();
if (ok) {
System.out.println("比较结果为: 正确(right)");
} else {
System.out.println("比较结果为: 错误(error)");
}

// System.out.println();
// System.out.println("<---");
}

public static void runTestCases(Class<?> clazz) {
java.lang.reflect.Method[] methods = clazz.getDeclaredMethods();
java.util.Arrays.sort(methods, (o1, o2) -> {
return o1.getName().compareTo(o2.getName());
});
for (java.lang.reflect.Method method : methods) {
if (method.getName().startsWith("test")) {
System.out.println(String.format("--- %s --->", method.getName()));

Object object = null;
try {
object = method.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println(String.format("<--- %s ---", method.getName()));

if (object instanceof Boolean) {
Boolean ok = (Boolean) object;
if (!ok) {
break;
}
} else {
throw new RuntimeException(String.format("测试用例方法%s的返回值需要为布尔类型", method.getName()));
}
}
}
}

public static Object[] toArray(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0];
}

return list.toArray();
}

public static Object[][] toArrays(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0][0];
}

Object[][] arrays = new Object[list.size()][];
for (int i = 0; i < list.size(); i++) {
arrays[i] = toArray(list.get(i));
}

return arrays;
}

@SuppressWarnings("unchecked")
public static <T> T[] genArray(Class<T> clazz, int length) {
return (T[]) java.lang.reflect.Array.newInstance(clazz, length);
}

@SuppressWarnings("unchecked")
public static <T> T[][] genArrays(Class<T> clazz, int rows, int cols) {
T[] array = genArray(clazz, 0);

T[][] arrays = (T[][]) genArray(array.getClass(), rows);
for (int i = 0; i < arrays.length; i++) {
arrays[i] = genArray(clazz, cols);
}

return arrays;
}

public static <T> T[] toArray(java.util.List<T> list, Class<T> clazz) {
if (list == null || list.isEmpty()) {
return genArray(clazz, 0);
}

T[] array = genArray(clazz, list.size());
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}

return array;
}

public static <T> T[][] toArrays(java.util.List<java.util.List<T>> lists, Class<T> clazz) {
if (lists == null || lists.isEmpty()) {
return genArrays(clazz, 0, 0);
}

T[][] arrays = genArrays(clazz, lists.size(), 0);
for (int i = 0; i < lists.size(); i++) {
arrays[i] = toArray(lists.get(i), clazz);
}

return arrays;
}

public static <T> java.util.List<T> toList(T[] array) {
return java.util.Arrays.asList(array);
}

public static <T> java.util.List<java.util.List<T>> toLists(T[][] arrays) {
java.util.List<java.util.List<T>> lists = new java.util.ArrayList<>();
for (T[] array : arrays) {
lists.add(toList(array));
}

return lists;
}
}
}

二叉树的中序遍历

题目描述

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
给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。



示例 1:

输入:root = [1,null,2,3]
输出:[1,3,2]
示例 2:

输入:root = []
输出:[]
示例 3:

输入:root = [1]
输出:[1]


提示:

树中节点数目在范围 [0, 100] 内
-100 <= Node.val <= 100


进阶: 递归算法很简单,你可以通过迭代算法完成吗?

题目解答

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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
import java.util.LinkedList;
import java.util.List;

public class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
if (root == null) {
return new LinkedList<>();
}

List<Integer> list = new LinkedList<>();

list.addAll(inorderTraversal(root.left));
list.add(root.val);
list.addAll(inorderTraversal(root.right));

return list;
}

static class TreeNode {
int val;
TreeNode left;
TreeNode right;

TreeNode() {
}

TreeNode(int val) {
this.val = val;
}

TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}

public static TreeNode genTree(Integer[] array) {
if (array.length == 0) {
return null;
}

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
TreeNode root = new TreeNode(array[0]);
queue.offer(root);

Integer v = null;
int i = 1;
while (i < array.length) {
TreeNode node = queue.poll();

TreeNode left = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;
TreeNode right = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;

// 数组中不包含空节点的子节点的写法(不标准的完全二叉树含空节点的层次遍历)
node.left = left;
node.right = right;
if (left != null) {
queue.offer(left);
}
if (right != null) {
queue.offer(right);
}

// 数组中包含空节点的子节点的写法(标准的完全二叉树含空节点的层次遍历)
// if (node != null) {
// node.left = left;
// node.right = right;
// }
// queue.offer(left);
// queue.offer(right);
}

return root;
}

public static Integer[] toArray(TreeNode root) {
if (root == null) {
return new Integer[0];
}

java.util.LinkedList<Integer> list = new java.util.LinkedList<>();

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
boolean hasValidNode = false;

int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();

if (node != null) {
list.add(node.val);

queue.offer(node.left);
queue.offer(node.right);

if (!hasValidNode) {
hasValidNode = node.left != null || node.right != null;
}
} else {
list.add(null);
}
}

if (!hasValidNode) {
// while (!queue.isEmpty()) {
// queue.poll();
// }

break;
}
}

while (!list.isEmpty() && list.get(list.size() - 1) == null) {
list.remove(list.size() - 1);
}

return list.toArray(new Integer[0]);
}
}
}

class TestMain {

public static void main(String[] args) {
TestUtils.runTestCases(TestCase.class);
}

public static class TestCase {

public static boolean testCase1() {
Integer[] nums = { 1, null, 2, 3 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<Integer> result = new Solution().inorderTraversal(tree);
Integer[] expect = { 1, 3, 2 };

return TestUtils.check(result, expect);
}

public static boolean testCase2() {
Integer[] nums = {};

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<Integer> result = new Solution().inorderTraversal(tree);
Integer[] expect = {};

return TestUtils.check(result, expect);
}

public static boolean testCase3() {
Integer[] nums = { 1 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<Integer> result = new Solution().inorderTraversal(tree);
Integer[] expect = { 1 };

return TestUtils.check(result, expect);
}
}

public static class TestUtils {

public static boolean check(Object result, Object expect) {
result = normalizeObject(result);
expect = normalizeObject(expect);
boolean ok = java.util.Objects.deepEquals(result, expect);
printCheck(toString(result), toString(expect), ok);
return ok;
}

public static boolean check(Object result, String expect) {
boolean ok = java.util.Objects.equals(normalizeString(toString(result)),
normalizeString(toString(expect)));
printCheck(normalizeString(toString(result)), normalizeString(toString(expect)), ok);
return ok;
}

private static Object normalizeObject(Object o) {
if (o instanceof java.util.List) {
java.util.List<?> list = (java.util.List<?>) o;
if (list != null && !list.isEmpty() && list.get(0) instanceof java.util.List) {
o = toArrays(list);
} else {
o = toArray(list);
}
}

return o;
}

private static String toString(Object o) {
if (o instanceof Object[]) {
return java.util.Arrays.deepToString((Object[]) o);
} else if (o instanceof int[]) {
return java.util.Arrays.toString((int[]) o);
} else if (o instanceof double[]) {
return java.util.Arrays.toString((double[]) o);
} else if (o instanceof char[]) {
return java.util.Arrays.toString((char[]) o);
} else {
return java.util.Objects.toString(o);
}
}

private static String normalizeString(String s) {
boolean isArray = (s.startsWith("{") && s.endsWith("}")) || (s.startsWith("[") && s.endsWith("]"));
if (isArray) {
s = s.replace(" ", "")
.replace("'", "")
.replace("\"", "")
.replace("{", "[")
.replace("}", "]");
}

return s;
}

private static void printCheck(String result, String expect, boolean ok) {
// System.out.println();
// System.out.println("--->");

System.out.println("result: " + result);
System.out.println("expect: " + expect);

System.out.println();
if (ok) {
System.out.println("比较结果为: 正确(right)");
} else {
System.out.println("比较结果为: 错误(error)");
}

// System.out.println();
// System.out.println("<---");
}

public static void runTestCases(Class<?> clazz) {
java.lang.reflect.Method[] methods = clazz.getDeclaredMethods();
java.util.Arrays.sort(methods, (o1, o2) -> {
return o1.getName().compareTo(o2.getName());
});
for (java.lang.reflect.Method method : methods) {
if (method.getName().startsWith("test")) {
System.out.println(String.format("--- %s --->", method.getName()));

Object object = null;
try {
object = method.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println(String.format("<--- %s ---", method.getName()));

if (object instanceof Boolean) {
Boolean ok = (Boolean) object;
if (!ok) {
break;
}
} else {
throw new RuntimeException(String.format("测试用例方法%s的返回值需要为布尔类型", method.getName()));
}
}
}
}

public static Object[] toArray(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0];
}

return list.toArray();
}

public static Object[][] toArrays(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0][0];
}

Object[][] arrays = new Object[list.size()][];
for (int i = 0; i < list.size(); i++) {
arrays[i] = toArray(list.get(i));
}

return arrays;
}

@SuppressWarnings("unchecked")
public static <T> T[] genArray(Class<T> clazz, int length) {
return (T[]) java.lang.reflect.Array.newInstance(clazz, length);
}

@SuppressWarnings("unchecked")
public static <T> T[][] genArrays(Class<T> clazz, int rows, int cols) {
T[] array = genArray(clazz, 0);

T[][] arrays = (T[][]) genArray(array.getClass(), rows);
for (int i = 0; i < arrays.length; i++) {
arrays[i] = genArray(clazz, cols);
}

return arrays;
}

public static <T> T[] toArray(java.util.List<T> list, Class<T> clazz) {
if (list == null || list.isEmpty()) {
return genArray(clazz, 0);
}

T[] array = genArray(clazz, list.size());
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}

return array;
}

public static <T> T[][] toArrays(java.util.List<java.util.List<T>> lists, Class<T> clazz) {
if (lists == null || lists.isEmpty()) {
return genArrays(clazz, 0, 0);
}

T[][] arrays = genArrays(clazz, lists.size(), 0);
for (int i = 0; i < lists.size(); i++) {
arrays[i] = toArray(lists.get(i), clazz);
}

return arrays;
}

public static <T> java.util.List<T> toList(T[] array) {
return java.util.Arrays.asList(array);
}

public static <T> java.util.List<java.util.List<T>> toLists(T[][] arrays) {
java.util.List<java.util.List<T>> lists = new java.util.ArrayList<>();
for (T[] array : arrays) {
lists.add(toList(array));
}

return lists;
}
}
}

进阶解法

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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
import java.util.Deque;
import java.util.LinkedList;
import java.util.List;

public class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
if (root == null) {
return new LinkedList<>();
}

List<Integer> list = new LinkedList<>();

Deque<TreeNode> stack = new LinkedList<>();

TreeNode p = root;
while (p != null || !stack.isEmpty()) {
if (p != null) {

stack.push(p);

p = p.left;
} else {
p = stack.pop();

list.add(p.val);

p = p.right;
}
}

return list;
}

static class TreeNode {
int val;
TreeNode left;
TreeNode right;

TreeNode() {
}

TreeNode(int val) {
this.val = val;
}

TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}

public static TreeNode genTree(Integer[] array) {
if (array.length == 0) {
return null;
}

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
TreeNode root = new TreeNode(array[0]);
queue.offer(root);

Integer v = null;
int i = 1;
while (i < array.length) {
TreeNode node = queue.poll();

TreeNode left = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;
TreeNode right = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;

// 数组中不包含空节点的子节点的写法(不标准的完全二叉树含空节点的层次遍历)
node.left = left;
node.right = right;
if (left != null) {
queue.offer(left);
}
if (right != null) {
queue.offer(right);
}

// 数组中包含空节点的子节点的写法(标准的完全二叉树含空节点的层次遍历)
// if (node != null) {
// node.left = left;
// node.right = right;
// }
// queue.offer(left);
// queue.offer(right);
}

return root;
}

public static Integer[] toArray(TreeNode root) {
if (root == null) {
return new Integer[0];
}

java.util.LinkedList<Integer> list = new java.util.LinkedList<>();

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
boolean hasValidNode = false;

int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();

if (node != null) {
list.add(node.val);

queue.offer(node.left);
queue.offer(node.right);

if (!hasValidNode) {
hasValidNode = node.left != null || node.right != null;
}
} else {
list.add(null);
}
}

if (!hasValidNode) {
// while (!queue.isEmpty()) {
// queue.poll();
// }

break;
}
}

while (!list.isEmpty() && list.get(list.size() - 1) == null) {
list.remove(list.size() - 1);
}

return list.toArray(new Integer[0]);
}
}
}

class TestMain {

public static void main(String[] args) {
TestUtils.runTestCases(TestCase.class);
}

public static class TestCase {

public static boolean testCase1() {
Integer[] nums = { 1, null, 2, 3 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<Integer> result = new Solution().inorderTraversal(tree);
Integer[] expect = { 1, 3, 2 };

return TestUtils.check(result, expect);
}

public static boolean testCase2() {
Integer[] nums = {};

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<Integer> result = new Solution().inorderTraversal(tree);
Integer[] expect = {};

return TestUtils.check(result, expect);
}

public static boolean testCase3() {
Integer[] nums = { 1 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<Integer> result = new Solution().inorderTraversal(tree);
Integer[] expect = { 1 };

return TestUtils.check(result, expect);
}
}

public static class TestUtils {

public static boolean check(Object result, Object expect) {
result = normalizeObject(result);
expect = normalizeObject(expect);
boolean ok = java.util.Objects.deepEquals(result, expect);
printCheck(toString(result), toString(expect), ok);
return ok;
}

public static boolean check(Object result, String expect) {
boolean ok = java.util.Objects.equals(normalizeString(toString(result)),
normalizeString(toString(expect)));
printCheck(normalizeString(toString(result)), normalizeString(toString(expect)), ok);
return ok;
}

private static Object normalizeObject(Object o) {
if (o instanceof java.util.List) {
java.util.List<?> list = (java.util.List<?>) o;
if (list != null && !list.isEmpty() && list.get(0) instanceof java.util.List) {
o = toArrays(list);
} else {
o = toArray(list);
}
}

return o;
}

private static String toString(Object o) {
if (o instanceof Object[]) {
return java.util.Arrays.deepToString((Object[]) o);
} else if (o instanceof int[]) {
return java.util.Arrays.toString((int[]) o);
} else if (o instanceof double[]) {
return java.util.Arrays.toString((double[]) o);
} else if (o instanceof char[]) {
return java.util.Arrays.toString((char[]) o);
} else {
return java.util.Objects.toString(o);
}
}

private static String normalizeString(String s) {
boolean isArray = (s.startsWith("{") && s.endsWith("}")) || (s.startsWith("[") && s.endsWith("]"));
if (isArray) {
s = s.replace(" ", "")
.replace("'", "")
.replace("\"", "")
.replace("{", "[")
.replace("}", "]");
}

return s;
}

private static void printCheck(String result, String expect, boolean ok) {
// System.out.println();
// System.out.println("--->");

System.out.println("result: " + result);
System.out.println("expect: " + expect);

System.out.println();
if (ok) {
System.out.println("比较结果为: 正确(right)");
} else {
System.out.println("比较结果为: 错误(error)");
}

// System.out.println();
// System.out.println("<---");
}

public static void runTestCases(Class<?> clazz) {
java.lang.reflect.Method[] methods = clazz.getDeclaredMethods();
java.util.Arrays.sort(methods, (o1, o2) -> {
return o1.getName().compareTo(o2.getName());
});
for (java.lang.reflect.Method method : methods) {
if (method.getName().startsWith("test")) {
System.out.println(String.format("--- %s --->", method.getName()));

Object object = null;
try {
object = method.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println(String.format("<--- %s ---", method.getName()));

if (object instanceof Boolean) {
Boolean ok = (Boolean) object;
if (!ok) {
break;
}
} else {
throw new RuntimeException(String.format("测试用例方法%s的返回值需要为布尔类型", method.getName()));
}
}
}
}

public static Object[] toArray(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0];
}

return list.toArray();
}

public static Object[][] toArrays(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0][0];
}

Object[][] arrays = new Object[list.size()][];
for (int i = 0; i < list.size(); i++) {
arrays[i] = toArray(list.get(i));
}

return arrays;
}

@SuppressWarnings("unchecked")
public static <T> T[] genArray(Class<T> clazz, int length) {
return (T[]) java.lang.reflect.Array.newInstance(clazz, length);
}

@SuppressWarnings("unchecked")
public static <T> T[][] genArrays(Class<T> clazz, int rows, int cols) {
T[] array = genArray(clazz, 0);

T[][] arrays = (T[][]) genArray(array.getClass(), rows);
for (int i = 0; i < arrays.length; i++) {
arrays[i] = genArray(clazz, cols);
}

return arrays;
}

public static <T> T[] toArray(java.util.List<T> list, Class<T> clazz) {
if (list == null || list.isEmpty()) {
return genArray(clazz, 0);
}

T[] array = genArray(clazz, list.size());
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}

return array;
}

public static <T> T[][] toArrays(java.util.List<java.util.List<T>> lists, Class<T> clazz) {
if (lists == null || lists.isEmpty()) {
return genArrays(clazz, 0, 0);
}

T[][] arrays = genArrays(clazz, lists.size(), 0);
for (int i = 0; i < lists.size(); i++) {
arrays[i] = toArray(lists.get(i), clazz);
}

return arrays;
}

public static <T> java.util.List<T> toList(T[] array) {
return java.util.Arrays.asList(array);
}

public static <T> java.util.List<java.util.List<T>> toLists(T[][] arrays) {
java.util.List<java.util.List<T>> lists = new java.util.ArrayList<>();
for (T[] array : arrays) {
lists.add(toList(array));
}

return lists;
}
}
}

二叉树的后序遍历

题目描述

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
给你一棵二叉树的根节点 root ,返回其节点值的 后序遍历 。



示例 1:

输入:root = [1,null,2,3]
输出:[3,2,1]
示例 2:

输入:root = []
输出:[]
示例 3:

输入:root = [1]
输出:[1]


提示:

树中节点的数目在范围 [0, 100] 内
-100 <= Node.val <= 100


进阶:递归算法很简单,你可以通过迭代算法完成吗?

题目解答

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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
import java.util.LinkedList;
import java.util.List;

public class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
if (root == null) {
return new LinkedList<>();
}

List<Integer> list = new LinkedList<>();

list.addAll(postorderTraversal(root.left));
list.addAll(postorderTraversal(root.right));
list.add(root.val);

return list;
}

static class TreeNode {
int val;
TreeNode left;
TreeNode right;

TreeNode() {
}

TreeNode(int val) {
this.val = val;
}

TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}

public static TreeNode genTree(Integer[] array) {
if (array.length == 0) {
return null;
}

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
TreeNode root = new TreeNode(array[0]);
queue.offer(root);

Integer v = null;
int i = 1;
while (i < array.length) {
TreeNode node = queue.poll();

TreeNode left = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;
TreeNode right = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;

// 数组中不包含空节点的子节点的写法(不标准的完全二叉树含空节点的层次遍历)
node.left = left;
node.right = right;
if (left != null) {
queue.offer(left);
}
if (right != null) {
queue.offer(right);
}

// 数组中包含空节点的子节点的写法(标准的完全二叉树含空节点的层次遍历)
// if (node != null) {
// node.left = left;
// node.right = right;
// }
// queue.offer(left);
// queue.offer(right);
}

return root;
}

public static Integer[] toArray(TreeNode root) {
if (root == null) {
return new Integer[0];
}

java.util.LinkedList<Integer> list = new java.util.LinkedList<>();

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
boolean hasValidNode = false;

int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();

if (node != null) {
list.add(node.val);

queue.offer(node.left);
queue.offer(node.right);

if (!hasValidNode) {
hasValidNode = node.left != null || node.right != null;
}
} else {
list.add(null);
}
}

if (!hasValidNode) {
// while (!queue.isEmpty()) {
// queue.poll();
// }

break;
}
}

while (!list.isEmpty() && list.get(list.size() - 1) == null) {
list.remove(list.size() - 1);
}

return list.toArray(new Integer[0]);
}
}
}

class TestMain {

public static void main(String[] args) {
TestUtils.runTestCases(TestCase.class);
}

public static class TestCase {

public static boolean testCase1() {
Integer[] nums = { 1, null, 2, 3 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<Integer> result = new Solution().postorderTraversal(tree);
Integer[] expect = { 3, 2, 1 };

return TestUtils.check(result, expect);
}

public static boolean testCase2() {
Integer[] nums = {};

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<Integer> result = new Solution().postorderTraversal(tree);
Integer[] expect = {};

return TestUtils.check(result, expect);
}

public static boolean testCase3() {
Integer[] nums = { 1 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<Integer> result = new Solution().postorderTraversal(tree);
Integer[] expect = { 1 };

return TestUtils.check(result, expect);
}
}

public static class TestUtils {

public static boolean check(Object result, Object expect) {
result = normalizeObject(result);
expect = normalizeObject(expect);
boolean ok = java.util.Objects.deepEquals(result, expect);
printCheck(toString(result), toString(expect), ok);
return ok;
}

public static boolean check(Object result, String expect) {
boolean ok = java.util.Objects.equals(normalizeString(toString(result)),
normalizeString(toString(expect)));
printCheck(normalizeString(toString(result)), normalizeString(toString(expect)), ok);
return ok;
}

private static Object normalizeObject(Object o) {
if (o instanceof java.util.List) {
java.util.List<?> list = (java.util.List<?>) o;
if (list != null && !list.isEmpty() && list.get(0) instanceof java.util.List) {
o = toArrays(list);
} else {
o = toArray(list);
}
}

return o;
}

private static String toString(Object o) {
if (o instanceof Object[]) {
return java.util.Arrays.deepToString((Object[]) o);
} else if (o instanceof int[]) {
return java.util.Arrays.toString((int[]) o);
} else if (o instanceof double[]) {
return java.util.Arrays.toString((double[]) o);
} else if (o instanceof char[]) {
return java.util.Arrays.toString((char[]) o);
} else {
return java.util.Objects.toString(o);
}
}

private static String normalizeString(String s) {
boolean isArray = (s.startsWith("{") && s.endsWith("}")) || (s.startsWith("[") && s.endsWith("]"));
if (isArray) {
s = s.replace(" ", "")
.replace("'", "")
.replace("\"", "")
.replace("{", "[")
.replace("}", "]");
}

return s;
}

private static void printCheck(String result, String expect, boolean ok) {
// System.out.println();
// System.out.println("--->");

System.out.println("result: " + result);
System.out.println("expect: " + expect);

System.out.println();
if (ok) {
System.out.println("比较结果为: 正确(right)");
} else {
System.out.println("比较结果为: 错误(error)");
}

// System.out.println();
// System.out.println("<---");
}

public static void runTestCases(Class<?> clazz) {
java.lang.reflect.Method[] methods = clazz.getDeclaredMethods();
java.util.Arrays.sort(methods, (o1, o2) -> {
return o1.getName().compareTo(o2.getName());
});
for (java.lang.reflect.Method method : methods) {
if (method.getName().startsWith("test")) {
System.out.println(String.format("--- %s --->", method.getName()));

Object object = null;
try {
object = method.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println(String.format("<--- %s ---", method.getName()));

if (object instanceof Boolean) {
Boolean ok = (Boolean) object;
if (!ok) {
break;
}
} else {
throw new RuntimeException(String.format("测试用例方法%s的返回值需要为布尔类型", method.getName()));
}
}
}
}

public static Object[] toArray(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0];
}

return list.toArray();
}

public static Object[][] toArrays(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0][0];
}

Object[][] arrays = new Object[list.size()][];
for (int i = 0; i < list.size(); i++) {
arrays[i] = toArray(list.get(i));
}

return arrays;
}

@SuppressWarnings("unchecked")
public static <T> T[] genArray(Class<T> clazz, int length) {
return (T[]) java.lang.reflect.Array.newInstance(clazz, length);
}

@SuppressWarnings("unchecked")
public static <T> T[][] genArrays(Class<T> clazz, int rows, int cols) {
T[] array = genArray(clazz, 0);

T[][] arrays = (T[][]) genArray(array.getClass(), rows);
for (int i = 0; i < arrays.length; i++) {
arrays[i] = genArray(clazz, cols);
}

return arrays;
}

public static <T> T[] toArray(java.util.List<T> list, Class<T> clazz) {
if (list == null || list.isEmpty()) {
return genArray(clazz, 0);
}

T[] array = genArray(clazz, list.size());
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}

return array;
}

public static <T> T[][] toArrays(java.util.List<java.util.List<T>> lists, Class<T> clazz) {
if (lists == null || lists.isEmpty()) {
return genArrays(clazz, 0, 0);
}

T[][] arrays = genArrays(clazz, lists.size(), 0);
for (int i = 0; i < lists.size(); i++) {
arrays[i] = toArray(lists.get(i), clazz);
}

return arrays;
}

public static <T> java.util.List<T> toList(T[] array) {
return java.util.Arrays.asList(array);
}

public static <T> java.util.List<java.util.List<T>> toLists(T[][] arrays) {
java.util.List<java.util.List<T>> lists = new java.util.ArrayList<>();
for (T[] array : arrays) {
lists.add(toList(array));
}

return lists;
}
}
}

进阶解法

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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
import java.util.Deque;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

public class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
if (root == null) {
return new LinkedList<>();
}

List<Integer> list = new LinkedList<>();

Map<TreeNode, Integer> map = new HashMap<>();

Deque<TreeNode> stack = new LinkedList<>();

TreeNode p = root;
while (p != null || !stack.isEmpty()) {
if (p != null) {
Integer flag = map.getOrDefault(p, 0);

if (flag == 0) {
map.put(p, ++flag);

stack.push(p);

p = p.left;
} else if (flag == 1) {
map.put(p, ++flag);

stack.push(p);

p = p.right;
} else {
list.add(p.val);

// p = stack.isEmpty() ? null : stack.pop();
p = null;
}
} else {
p = stack.pop();
}
}

return list;
}

static class TreeNode {
int val;
TreeNode left;
TreeNode right;

TreeNode() {
}

TreeNode(int val) {
this.val = val;
}

TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}

public static TreeNode genTree(Integer[] array) {
if (array.length == 0) {
return null;
}

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
TreeNode root = new TreeNode(array[0]);
queue.offer(root);

Integer v = null;
int i = 1;
while (i < array.length) {
TreeNode node = queue.poll();

TreeNode left = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;
TreeNode right = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;

// 数组中不包含空节点的子节点的写法(不标准的完全二叉树含空节点的层次遍历)
node.left = left;
node.right = right;
if (left != null) {
queue.offer(left);
}
if (right != null) {
queue.offer(right);
}

// 数组中包含空节点的子节点的写法(标准的完全二叉树含空节点的层次遍历)
// if (node != null) {
// node.left = left;
// node.right = right;
// }
// queue.offer(left);
// queue.offer(right);
}

return root;
}

public static Integer[] toArray(TreeNode root) {
if (root == null) {
return new Integer[0];
}

java.util.LinkedList<Integer> list = new java.util.LinkedList<>();

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
boolean hasValidNode = false;

int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();

if (node != null) {
list.add(node.val);

queue.offer(node.left);
queue.offer(node.right);

if (!hasValidNode) {
hasValidNode = node.left != null || node.right != null;
}
} else {
list.add(null);
}
}

if (!hasValidNode) {
// while (!queue.isEmpty()) {
// queue.poll();
// }

break;
}
}

while (!list.isEmpty() && list.get(list.size() - 1) == null) {
list.remove(list.size() - 1);
}

return list.toArray(new Integer[0]);
}
}
}

class TestMain {

public static void main(String[] args) {
TestUtils.runTestCases(TestCase.class);
}

public static class TestCase {

public static boolean testCase1() {
Integer[] nums = { 1, null, 2, 3 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<Integer> result = new Solution().postorderTraversal(tree);
Integer[] expect = { 3, 2, 1 };

return TestUtils.check(result, expect);
}

public static boolean testCase2() {
Integer[] nums = {};

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<Integer> result = new Solution().postorderTraversal(tree);
Integer[] expect = {};

return TestUtils.check(result, expect);
}

public static boolean testCase3() {
Integer[] nums = { 1 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<Integer> result = new Solution().postorderTraversal(tree);
Integer[] expect = { 1 };

return TestUtils.check(result, expect);
}
}

public static class TestUtils {

public static boolean check(Object result, Object expect) {
result = normalizeObject(result);
expect = normalizeObject(expect);
boolean ok = java.util.Objects.deepEquals(result, expect);
printCheck(toString(result), toString(expect), ok);
return ok;
}

public static boolean check(Object result, String expect) {
boolean ok = java.util.Objects.equals(normalizeString(toString(result)),
normalizeString(toString(expect)));
printCheck(normalizeString(toString(result)), normalizeString(toString(expect)), ok);
return ok;
}

private static Object normalizeObject(Object o) {
if (o instanceof java.util.List) {
java.util.List<?> list = (java.util.List<?>) o;
if (list != null && !list.isEmpty() && list.get(0) instanceof java.util.List) {
o = toArrays(list);
} else {
o = toArray(list);
}
}

return o;
}

private static String toString(Object o) {
if (o instanceof Object[]) {
return java.util.Arrays.deepToString((Object[]) o);
} else if (o instanceof int[]) {
return java.util.Arrays.toString((int[]) o);
} else if (o instanceof double[]) {
return java.util.Arrays.toString((double[]) o);
} else if (o instanceof char[]) {
return java.util.Arrays.toString((char[]) o);
} else {
return java.util.Objects.toString(o);
}
}

private static String normalizeString(String s) {
boolean isArray = (s.startsWith("{") && s.endsWith("}")) || (s.startsWith("[") && s.endsWith("]"));
if (isArray) {
s = s.replace(" ", "")
.replace("'", "")
.replace("\"", "")
.replace("{", "[")
.replace("}", "]");
}

return s;
}

private static void printCheck(String result, String expect, boolean ok) {
// System.out.println();
// System.out.println("--->");

System.out.println("result: " + result);
System.out.println("expect: " + expect);

System.out.println();
if (ok) {
System.out.println("比较结果为: 正确(right)");
} else {
System.out.println("比较结果为: 错误(error)");
}

// System.out.println();
// System.out.println("<---");
}

public static void runTestCases(Class<?> clazz) {
java.lang.reflect.Method[] methods = clazz.getDeclaredMethods();
java.util.Arrays.sort(methods, (o1, o2) -> {
return o1.getName().compareTo(o2.getName());
});
for (java.lang.reflect.Method method : methods) {
if (method.getName().startsWith("test")) {
System.out.println(String.format("--- %s --->", method.getName()));

Object object = null;
try {
object = method.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println(String.format("<--- %s ---", method.getName()));

if (object instanceof Boolean) {
Boolean ok = (Boolean) object;
if (!ok) {
break;
}
} else {
throw new RuntimeException(String.format("测试用例方法%s的返回值需要为布尔类型", method.getName()));
}
}
}
}

public static Object[] toArray(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0];
}

return list.toArray();
}

public static Object[][] toArrays(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0][0];
}

Object[][] arrays = new Object[list.size()][];
for (int i = 0; i < list.size(); i++) {
arrays[i] = toArray(list.get(i));
}

return arrays;
}

@SuppressWarnings("unchecked")
public static <T> T[] genArray(Class<T> clazz, int length) {
return (T[]) java.lang.reflect.Array.newInstance(clazz, length);
}

@SuppressWarnings("unchecked")
public static <T> T[][] genArrays(Class<T> clazz, int rows, int cols) {
T[] array = genArray(clazz, 0);

T[][] arrays = (T[][]) genArray(array.getClass(), rows);
for (int i = 0; i < arrays.length; i++) {
arrays[i] = genArray(clazz, cols);
}

return arrays;
}

public static <T> T[] toArray(java.util.List<T> list, Class<T> clazz) {
if (list == null || list.isEmpty()) {
return genArray(clazz, 0);
}

T[] array = genArray(clazz, list.size());
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}

return array;
}

public static <T> T[][] toArrays(java.util.List<java.util.List<T>> lists, Class<T> clazz) {
if (lists == null || lists.isEmpty()) {
return genArrays(clazz, 0, 0);
}

T[][] arrays = genArrays(clazz, lists.size(), 0);
for (int i = 0; i < lists.size(); i++) {
arrays[i] = toArray(lists.get(i), clazz);
}

return arrays;
}

public static <T> java.util.List<T> toList(T[] array) {
return java.util.Arrays.asList(array);
}

public static <T> java.util.List<java.util.List<T>> toLists(T[][] arrays) {
java.util.List<java.util.List<T>> lists = new java.util.ArrayList<>();
for (T[] array : arrays) {
lists.add(toList(array));
}

return lists;
}
}
}

二叉树的锯齿形层序遍历

题目描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
给你二叉树的根节点 root ,返回其节点值的 锯齿形层序遍历 。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。



示例 1:

输入:root = [3,9,20,null,null,15,7]
输出:[[3],[20,9],[15,7]]
示例 2:

输入:root = [1]
输出:[[1]]
示例 3:

输入:root = []
输出:[]


提示:

树中节点数目在范围 [0, 2000] 内
-100 <= Node.val <= 100

题目解答

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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

public class Solution {
public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
if (root == null) {
return new LinkedList<>();
}

List<List<Integer>> lists = new LinkedList<>();

boolean isOdd = true; // odd:奇数,even:偶数

Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
List<Integer> values = new LinkedList<>();

int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();

if (node.left != null) {
queue.offer(node.left);
}

if (node.right != null) {
queue.offer(node.right);
}

if (isOdd) {
values.add(node.val);
} else {
values.add(0, node.val);
}

}

lists.add(values);

isOdd = !isOdd;
}

return lists;
}

static class TreeNode {
int val;
TreeNode left;
TreeNode right;

TreeNode() {
}

TreeNode(int val) {
this.val = val;
}

TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}

public static TreeNode genTree(Integer[] array) {
if (array.length == 0) {
return null;
}

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
TreeNode root = new TreeNode(array[0]);
queue.offer(root);

Integer v = null;
int i = 1;
while (i < array.length) {
TreeNode node = queue.poll();

TreeNode left = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;
TreeNode right = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;

// 数组中不包含空节点的子节点的写法(不标准的完全二叉树含空节点的层次遍历)
node.left = left;
node.right = right;
if (left != null) {
queue.offer(left);
}
if (right != null) {
queue.offer(right);
}

// 数组中包含空节点的子节点的写法(标准的完全二叉树含空节点的层次遍历)
// if (node != null) {
// node.left = left;
// node.right = right;
// }
// queue.offer(left);
// queue.offer(right);
}

return root;
}

public static Integer[] toArray(TreeNode root) {
if (root == null) {
return new Integer[0];
}

java.util.LinkedList<Integer> list = new java.util.LinkedList<>();

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
boolean hasValidNode = false;

int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();

if (node != null) {
list.add(node.val);

queue.offer(node.left);
queue.offer(node.right);

if (!hasValidNode) {
hasValidNode = node.left != null || node.right != null;
}
} else {
list.add(null);
}
}

if (!hasValidNode) {
// while (!queue.isEmpty()) {
// queue.poll();
// }

break;
}
}

while (!list.isEmpty() && list.get(list.size() - 1) == null) {
list.remove(list.size() - 1);
}

return list.toArray(new Integer[0]);
}
}
}

class TestMain {

public static void main(String[] args) {
TestUtils.runTestCases(TestCase.class);
}

public static class TestCase {

public static boolean testCase1() {
Integer[] nums = { 3, 9, 20, null, null, 15, 7 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<List<Integer>> result = new Solution().zigzagLevelOrder(tree);
Integer[][] expect = { { 3 }, { 20, 9 }, { 15, 7 } };

return TestUtils.check(result, expect);
}

public static boolean testCase2() {
Integer[] nums = { 1 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<List<Integer>> result = new Solution().zigzagLevelOrder(tree);
Integer[][] expect = { { 1 } };

return TestUtils.check(result, expect);
}

public static boolean testCase3() {
Integer[] nums = {};

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<List<Integer>> result = new Solution().zigzagLevelOrder(tree);
Integer[][] expect = {};

return TestUtils.check(result, expect);
}
}

public static class TestUtils {

public static boolean check(Object result, Object expect) {
result = normalizeObject(result);
expect = normalizeObject(expect);
boolean ok = java.util.Objects.deepEquals(result, expect);
printCheck(toString(result), toString(expect), ok);
return ok;
}

public static boolean check(Object result, String expect) {
boolean ok = java.util.Objects.equals(normalizeString(toString(result)),
normalizeString(toString(expect)));
printCheck(normalizeString(toString(result)), normalizeString(toString(expect)), ok);
return ok;
}

private static Object normalizeObject(Object o) {
if (o instanceof java.util.List) {
java.util.List<?> list = (java.util.List<?>) o;
if (list != null && !list.isEmpty() && list.get(0) instanceof java.util.List) {
o = toArrays(list);
} else {
o = toArray(list);
}
}

return o;
}

private static String toString(Object o) {
if (o instanceof Object[]) {
return java.util.Arrays.deepToString((Object[]) o);
} else if (o instanceof int[]) {
return java.util.Arrays.toString((int[]) o);
} else if (o instanceof double[]) {
return java.util.Arrays.toString((double[]) o);
} else if (o instanceof char[]) {
return java.util.Arrays.toString((char[]) o);
} else {
return java.util.Objects.toString(o);
}
}

private static String normalizeString(String s) {
boolean isArray = (s.startsWith("{") && s.endsWith("}")) || (s.startsWith("[") && s.endsWith("]"));
if (isArray) {
s = s.replace(" ", "")
.replace("'", "")
.replace("\"", "")
.replace("{", "[")
.replace("}", "]");
}

return s;
}

private static void printCheck(String result, String expect, boolean ok) {
// System.out.println();
// System.out.println("--->");

System.out.println("result: " + result);
System.out.println("expect: " + expect);

System.out.println();
if (ok) {
System.out.println("比较结果为: 正确(right)");
} else {
System.out.println("比较结果为: 错误(error)");
}

// System.out.println();
// System.out.println("<---");
}

public static void runTestCases(Class<?> clazz) {
java.lang.reflect.Method[] methods = clazz.getDeclaredMethods();
java.util.Arrays.sort(methods, (o1, o2) -> {
return o1.getName().compareTo(o2.getName());
});
for (java.lang.reflect.Method method : methods) {
if (method.getName().startsWith("test")) {
System.out.println(String.format("--- %s --->", method.getName()));

Object object = null;
try {
object = method.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println(String.format("<--- %s ---", method.getName()));

if (object instanceof Boolean) {
Boolean ok = (Boolean) object;
if (!ok) {
break;
}
} else {
throw new RuntimeException(String.format("测试用例方法%s的返回值需要为布尔类型", method.getName()));
}
}
}
}

public static Object[] toArray(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0];
}

return list.toArray();
}

public static Object[][] toArrays(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0][0];
}

Object[][] arrays = new Object[list.size()][];
for (int i = 0; i < list.size(); i++) {
arrays[i] = toArray(list.get(i));
}

return arrays;
}

@SuppressWarnings("unchecked")
public static <T> T[] genArray(Class<T> clazz, int length) {
return (T[]) java.lang.reflect.Array.newInstance(clazz, length);
}

@SuppressWarnings("unchecked")
public static <T> T[][] genArrays(Class<T> clazz, int rows, int cols) {
T[] array = genArray(clazz, 0);

T[][] arrays = (T[][]) genArray(array.getClass(), rows);
for (int i = 0; i < arrays.length; i++) {
arrays[i] = genArray(clazz, cols);
}

return arrays;
}

public static <T> T[] toArray(java.util.List<T> list, Class<T> clazz) {
if (list == null || list.isEmpty()) {
return genArray(clazz, 0);
}

T[] array = genArray(clazz, list.size());
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}

return array;
}

public static <T> T[][] toArrays(java.util.List<java.util.List<T>> lists, Class<T> clazz) {
if (lists == null || lists.isEmpty()) {
return genArrays(clazz, 0, 0);
}

T[][] arrays = genArrays(clazz, lists.size(), 0);
for (int i = 0; i < lists.size(); i++) {
arrays[i] = toArray(lists.get(i), clazz);
}

return arrays;
}

public static <T> java.util.List<T> toList(T[] array) {
return java.util.Arrays.asList(array);
}

public static <T> java.util.List<java.util.List<T>> toLists(T[][] arrays) {
java.util.List<java.util.List<T>> lists = new java.util.ArrayList<>();
for (T[] array : arrays) {
lists.add(toList(array));
}

return lists;
}
}
}

其他解法

解法1

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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

public class Solution {
public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
if (root == null) {
return new LinkedList<>();
}

List<List<Integer>> lists = new LinkedList<>();

boolean isOdd = true; // odd:奇数,even:偶数

Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
List<Integer> values = new LinkedList<>();

int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();

if (node.left != null) {
queue.offer(node.left);
}

if (node.right != null) {
queue.offer(node.right);
}

values.add(node.val);
}

if (!isOdd) {
Collections.reverse(values);
}

lists.add(values);

isOdd = !isOdd;
}

return lists;
}

static class TreeNode {
int val;
TreeNode left;
TreeNode right;

TreeNode() {
}

TreeNode(int val) {
this.val = val;
}

TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}

public static TreeNode genTree(Integer[] array) {
if (array.length == 0) {
return null;
}

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
TreeNode root = new TreeNode(array[0]);
queue.offer(root);

Integer v = null;
int i = 1;
while (i < array.length) {
TreeNode node = queue.poll();

TreeNode left = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;
TreeNode right = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;

// 数组中不包含空节点的子节点的写法(不标准的完全二叉树含空节点的层次遍历)
node.left = left;
node.right = right;
if (left != null) {
queue.offer(left);
}
if (right != null) {
queue.offer(right);
}

// 数组中包含空节点的子节点的写法(标准的完全二叉树含空节点的层次遍历)
// if (node != null) {
// node.left = left;
// node.right = right;
// }
// queue.offer(left);
// queue.offer(right);
}

return root;
}

public static Integer[] toArray(TreeNode root) {
if (root == null) {
return new Integer[0];
}

java.util.LinkedList<Integer> list = new java.util.LinkedList<>();

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
boolean hasValidNode = false;

int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();

if (node != null) {
list.add(node.val);

queue.offer(node.left);
queue.offer(node.right);

if (!hasValidNode) {
hasValidNode = node.left != null || node.right != null;
}
} else {
list.add(null);
}
}

if (!hasValidNode) {
// while (!queue.isEmpty()) {
// queue.poll();
// }

break;
}
}

while (!list.isEmpty() && list.get(list.size() - 1) == null) {
list.remove(list.size() - 1);
}

return list.toArray(new Integer[0]);
}
}
}

class TestMain {

public static void main(String[] args) {
TestUtils.runTestCases(TestCase.class);
}

public static class TestCase {

public static boolean testCase1() {
Integer[] nums = { 3, 9, 20, null, null, 15, 7 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<List<Integer>> result = new Solution().zigzagLevelOrder(tree);
Integer[][] expect = { { 3 }, { 20, 9 }, { 15, 7 } };

return TestUtils.check(result, expect);
}

public static boolean testCase2() {
Integer[] nums = { 1 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<List<Integer>> result = new Solution().zigzagLevelOrder(tree);
Integer[][] expect = { { 1 } };

return TestUtils.check(result, expect);
}

public static boolean testCase3() {
Integer[] nums = {};

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
List<List<Integer>> result = new Solution().zigzagLevelOrder(tree);
Integer[][] expect = {};

return TestUtils.check(result, expect);
}
}

public static class TestUtils {

public static boolean check(Object result, Object expect) {
result = normalizeObject(result);
expect = normalizeObject(expect);
boolean ok = java.util.Objects.deepEquals(result, expect);
printCheck(toString(result), toString(expect), ok);
return ok;
}

public static boolean check(Object result, String expect) {
boolean ok = java.util.Objects.equals(normalizeString(toString(result)),
normalizeString(toString(expect)));
printCheck(normalizeString(toString(result)), normalizeString(toString(expect)), ok);
return ok;
}

private static Object normalizeObject(Object o) {
if (o instanceof java.util.List) {
java.util.List<?> list = (java.util.List<?>) o;
if (list != null && !list.isEmpty() && list.get(0) instanceof java.util.List) {
o = toArrays(list);
} else {
o = toArray(list);
}
}

return o;
}

private static String toString(Object o) {
if (o instanceof Object[]) {
return java.util.Arrays.deepToString((Object[]) o);
} else if (o instanceof int[]) {
return java.util.Arrays.toString((int[]) o);
} else if (o instanceof double[]) {
return java.util.Arrays.toString((double[]) o);
} else if (o instanceof char[]) {
return java.util.Arrays.toString((char[]) o);
} else {
return java.util.Objects.toString(o);
}
}

private static String normalizeString(String s) {
boolean isArray = (s.startsWith("{") && s.endsWith("}")) || (s.startsWith("[") && s.endsWith("]"));
if (isArray) {
s = s.replace(" ", "")
.replace("'", "")
.replace("\"", "")
.replace("{", "[")
.replace("}", "]");
}

return s;
}

private static void printCheck(String result, String expect, boolean ok) {
// System.out.println();
// System.out.println("--->");

System.out.println("result: " + result);
System.out.println("expect: " + expect);

System.out.println();
if (ok) {
System.out.println("比较结果为: 正确(right)");
} else {
System.out.println("比较结果为: 错误(error)");
}

// System.out.println();
// System.out.println("<---");
}

public static void runTestCases(Class<?> clazz) {
java.lang.reflect.Method[] methods = clazz.getDeclaredMethods();
java.util.Arrays.sort(methods, (o1, o2) -> {
return o1.getName().compareTo(o2.getName());
});
for (java.lang.reflect.Method method : methods) {
if (method.getName().startsWith("test")) {
System.out.println(String.format("--- %s --->", method.getName()));

Object object = null;
try {
object = method.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println(String.format("<--- %s ---", method.getName()));

if (object instanceof Boolean) {
Boolean ok = (Boolean) object;
if (!ok) {
break;
}
} else {
throw new RuntimeException(String.format("测试用例方法%s的返回值需要为布尔类型", method.getName()));
}
}
}
}

public static Object[] toArray(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0];
}

return list.toArray();
}

public static Object[][] toArrays(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0][0];
}

Object[][] arrays = new Object[list.size()][];
for (int i = 0; i < list.size(); i++) {
arrays[i] = toArray(list.get(i));
}

return arrays;
}

@SuppressWarnings("unchecked")
public static <T> T[] genArray(Class<T> clazz, int length) {
return (T[]) java.lang.reflect.Array.newInstance(clazz, length);
}

@SuppressWarnings("unchecked")
public static <T> T[][] genArrays(Class<T> clazz, int rows, int cols) {
T[] array = genArray(clazz, 0);

T[][] arrays = (T[][]) genArray(array.getClass(), rows);
for (int i = 0; i < arrays.length; i++) {
arrays[i] = genArray(clazz, cols);
}

return arrays;
}

public static <T> T[] toArray(java.util.List<T> list, Class<T> clazz) {
if (list == null || list.isEmpty()) {
return genArray(clazz, 0);
}

T[] array = genArray(clazz, list.size());
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}

return array;
}

public static <T> T[][] toArrays(java.util.List<java.util.List<T>> lists, Class<T> clazz) {
if (lists == null || lists.isEmpty()) {
return genArrays(clazz, 0, 0);
}

T[][] arrays = genArrays(clazz, lists.size(), 0);
for (int i = 0; i < lists.size(); i++) {
arrays[i] = toArray(lists.get(i), clazz);
}

return arrays;
}

public static <T> java.util.List<T> toList(T[] array) {
return java.util.Arrays.asList(array);
}

public static <T> java.util.List<java.util.List<T>> toLists(T[][] arrays) {
java.util.List<java.util.List<T>> lists = new java.util.ArrayList<>();
for (T[] array : arrays) {
lists.add(toList(array));
}

return lists;
}
}
}

二叉搜索树的最小绝对差

题目描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
给你一个二叉搜索树的根节点 root ,返回 树中任意两不同节点值之间的最小差值 。

差值是一个正数,其数值等于两值之差的绝对值。



示例 1:

输入:root = [4,2,6,1,3]
输出:1
示例 2:

输入:root = [1,0,48,null,null,12,49]
输出:1


提示:

树中节点的数目范围是 [2, 104]
0 <= Node.val <= 105


注意:本题与 783 https://leetcode-cn.com/problems/minimum-distance-between-bst-nodes/ 相同

题目解答

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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
public class Solution {
private int min = Integer.MAX_VALUE;
private Integer pre = null;

public int getMinimumDifference(TreeNode root) {
if (root == null) {
return 0;
}

getMinimumDifference(root.left);

// 中序遍历时处理结点
if (pre != null && root.val - pre < min) {
min = root.val - pre;
}

pre = root.val;

getMinimumDifference(root.right);

return min;
}

static class TreeNode {
int val;
TreeNode left;
TreeNode right;

TreeNode() {
}

TreeNode(int val) {
this.val = val;
}

TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}

public static TreeNode genTree(Integer[] array) {
if (array.length == 0) {
return null;
}

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
TreeNode root = new TreeNode(array[0]);
queue.offer(root);

Integer v = null;
int i = 1;
while (i < array.length) {
TreeNode node = queue.poll();

TreeNode left = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;
TreeNode right = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;

// 数组中不包含空节点的子节点的写法(不标准的完全二叉树含空节点的层次遍历)
node.left = left;
node.right = right;
if (left != null) {
queue.offer(left);
}
if (right != null) {
queue.offer(right);
}

// 数组中包含空节点的子节点的写法(标准的完全二叉树含空节点的层次遍历)
// if (node != null) {
// node.left = left;
// node.right = right;
// }
// queue.offer(left);
// queue.offer(right);
}

return root;
}

public static Integer[] toArray(TreeNode root) {
if (root == null) {
return new Integer[0];
}

java.util.LinkedList<Integer> list = new java.util.LinkedList<>();

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
boolean hasValidNode = false;

int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();

if (node != null) {
list.add(node.val);

queue.offer(node.left);
queue.offer(node.right);

if (!hasValidNode) {
hasValidNode = node.left != null || node.right != null;
}
} else {
list.add(null);
}
}

if (!hasValidNode) {
// while (!queue.isEmpty()) {
// queue.poll();
// }

break;
}
}

while (!list.isEmpty() && list.get(list.size() - 1) == null) {
list.remove(list.size() - 1);
}

return list.toArray(new Integer[0]);
}
}
}

class TestMain {

public static void main(String[] args) {
TestUtils.runTestCases(TestCase.class);
}

public static class TestCase {

public static boolean testCase1() {
Integer[] nums = { 4, 2, 6, 1, 3 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
int result = new Solution().getMinimumDifference(tree);
int expect = 1;

return TestUtils.check(result, expect);
}

public static boolean testCase2() {
Integer[] nums = { 1, 0, 48, null, null, 12, 49 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
int result = new Solution().getMinimumDifference(tree);
int expect = 1;

return TestUtils.check(result, expect);
}
}

public static class TestUtils {

public static boolean check(Object result, Object expect) {
result = normalizeObject(result);
expect = normalizeObject(expect);
boolean ok = java.util.Objects.deepEquals(result, expect);
printCheck(toString(result), toString(expect), ok);
return ok;
}

public static boolean check(Object result, String expect) {
boolean ok = java.util.Objects.equals(normalizeString(toString(result)),
normalizeString(toString(expect)));
printCheck(normalizeString(toString(result)), normalizeString(toString(expect)), ok);
return ok;
}

private static Object normalizeObject(Object o) {
if (o instanceof java.util.List) {
java.util.List<?> list = (java.util.List<?>) o;
if (list != null && !list.isEmpty() && list.get(0) instanceof java.util.List) {
o = toArrays(list);
} else {
o = toArray(list);
}
}

return o;
}

private static String toString(Object o) {
if (o instanceof Object[]) {
return java.util.Arrays.deepToString((Object[]) o);
} else if (o instanceof int[]) {
return java.util.Arrays.toString((int[]) o);
} else if (o instanceof double[]) {
return java.util.Arrays.toString((double[]) o);
} else if (o instanceof char[]) {
return java.util.Arrays.toString((char[]) o);
} else {
return java.util.Objects.toString(o);
}
}

private static String normalizeString(String s) {
boolean isArray = (s.startsWith("{") && s.endsWith("}")) || (s.startsWith("[") && s.endsWith("]"));
if (isArray) {
s = s.replace(" ", "")
.replace("'", "")
.replace("\"", "")
.replace("{", "[")
.replace("}", "]");
}

return s;
}

private static void printCheck(String result, String expect, boolean ok) {
// System.out.println();
// System.out.println("--->");

System.out.println("result: " + result);
System.out.println("expect: " + expect);

System.out.println();
if (ok) {
System.out.println("比较结果为: 正确(right)");
} else {
System.out.println("比较结果为: 错误(error)");
}

// System.out.println();
// System.out.println("<---");
}

public static void runTestCases(Class<?> clazz) {
java.lang.reflect.Method[] methods = clazz.getDeclaredMethods();
java.util.Arrays.sort(methods, (o1, o2) -> {
return o1.getName().compareTo(o2.getName());
});
for (java.lang.reflect.Method method : methods) {
if (method.getName().startsWith("test")) {
System.out.println(String.format("--- %s --->", method.getName()));

Object object = null;
try {
object = method.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println(String.format("<--- %s ---", method.getName()));

if (object instanceof Boolean) {
Boolean ok = (Boolean) object;
if (!ok) {
break;
}
} else {
throw new RuntimeException(String.format("测试用例方法%s的返回值需要为布尔类型", method.getName()));
}
}
}
}

public static Object[] toArray(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0];
}

return list.toArray();
}

public static Object[][] toArrays(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0][0];
}

Object[][] arrays = new Object[list.size()][];
for (int i = 0; i < list.size(); i++) {
arrays[i] = toArray(list.get(i));
}

return arrays;
}

@SuppressWarnings("unchecked")
public static <T> T[] genArray(Class<T> clazz, int length) {
return (T[]) java.lang.reflect.Array.newInstance(clazz, length);
}

@SuppressWarnings("unchecked")
public static <T> T[][] genArrays(Class<T> clazz, int rows, int cols) {
T[] array = genArray(clazz, 0);

T[][] arrays = (T[][]) genArray(array.getClass(), rows);
for (int i = 0; i < arrays.length; i++) {
arrays[i] = genArray(clazz, cols);
}

return arrays;
}

public static <T> T[] toArray(java.util.List<T> list, Class<T> clazz) {
if (list == null || list.isEmpty()) {
return genArray(clazz, 0);
}

T[] array = genArray(clazz, list.size());
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}

return array;
}

public static <T> T[][] toArrays(java.util.List<java.util.List<T>> lists, Class<T> clazz) {
if (lists == null || lists.isEmpty()) {
return genArrays(clazz, 0, 0);
}

T[][] arrays = genArrays(clazz, lists.size(), 0);
for (int i = 0; i < lists.size(); i++) {
arrays[i] = toArray(lists.get(i), clazz);
}

return arrays;
}

public static <T> java.util.List<T> toList(T[] array) {
return java.util.Arrays.asList(array);
}

public static <T> java.util.List<java.util.List<T>> toLists(T[][] arrays) {
java.util.List<java.util.List<T>> lists = new java.util.ArrayList<>();
for (T[] array : arrays) {
lists.add(toList(array));
}

return lists;
}
}
}

进阶解法

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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
import java.util.Deque;
import java.util.LinkedList;

public class Solution {
public int getMinimumDifference(TreeNode root) {
if (root == null) {
return 0;
}

int min = Integer.MAX_VALUE;
Integer pre = null;

Deque<TreeNode> stack = new LinkedList<>();

TreeNode p = root;
while (p != null || !stack.isEmpty()) {
if (p != null) {

stack.push(p);

p = p.left;
} else {
p = stack.pop();

if (pre != null && p.val - pre < min) {
min = p.val - pre;
}

pre = p.val;

p = p.right;
}
}

return min;
}

static class TreeNode {
int val;
TreeNode left;
TreeNode right;

TreeNode() {
}

TreeNode(int val) {
this.val = val;
}

TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}

public static TreeNode genTree(Integer[] array) {
if (array.length == 0) {
return null;
}

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
TreeNode root = new TreeNode(array[0]);
queue.offer(root);

Integer v = null;
int i = 1;
while (i < array.length) {
TreeNode node = queue.poll();

TreeNode left = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;
TreeNode right = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;

// 数组中不包含空节点的子节点的写法(不标准的完全二叉树含空节点的层次遍历)
node.left = left;
node.right = right;
if (left != null) {
queue.offer(left);
}
if (right != null) {
queue.offer(right);
}

// 数组中包含空节点的子节点的写法(标准的完全二叉树含空节点的层次遍历)
// if (node != null) {
// node.left = left;
// node.right = right;
// }
// queue.offer(left);
// queue.offer(right);
}

return root;
}

public static Integer[] toArray(TreeNode root) {
if (root == null) {
return new Integer[0];
}

java.util.LinkedList<Integer> list = new java.util.LinkedList<>();

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
boolean hasValidNode = false;

int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();

if (node != null) {
list.add(node.val);

queue.offer(node.left);
queue.offer(node.right);

if (!hasValidNode) {
hasValidNode = node.left != null || node.right != null;
}
} else {
list.add(null);
}
}

if (!hasValidNode) {
// while (!queue.isEmpty()) {
// queue.poll();
// }

break;
}
}

while (!list.isEmpty() && list.get(list.size() - 1) == null) {
list.remove(list.size() - 1);
}

return list.toArray(new Integer[0]);
}
}
}

class TestMain {

public static void main(String[] args) {
TestUtils.runTestCases(TestCase.class);
}

public static class TestCase {

public static boolean testCase1() {
Integer[] nums = { 4, 2, 6, 1, 3 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
int result = new Solution().getMinimumDifference(tree);
int expect = 1;

return TestUtils.check(result, expect);
}

public static boolean testCase2() {
Integer[] nums = { 1, 0, 48, null, null, 12, 49 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
int result = new Solution().getMinimumDifference(tree);
int expect = 1;

return TestUtils.check(result, expect);
}
}

public static class TestUtils {

public static boolean check(Object result, Object expect) {
result = normalizeObject(result);
expect = normalizeObject(expect);
boolean ok = java.util.Objects.deepEquals(result, expect);
printCheck(toString(result), toString(expect), ok);
return ok;
}

public static boolean check(Object result, String expect) {
boolean ok = java.util.Objects.equals(normalizeString(toString(result)),
normalizeString(toString(expect)));
printCheck(normalizeString(toString(result)), normalizeString(toString(expect)), ok);
return ok;
}

private static Object normalizeObject(Object o) {
if (o instanceof java.util.List) {
java.util.List<?> list = (java.util.List<?>) o;
if (list != null && !list.isEmpty() && list.get(0) instanceof java.util.List) {
o = toArrays(list);
} else {
o = toArray(list);
}
}

return o;
}

private static String toString(Object o) {
if (o instanceof Object[]) {
return java.util.Arrays.deepToString((Object[]) o);
} else if (o instanceof int[]) {
return java.util.Arrays.toString((int[]) o);
} else if (o instanceof double[]) {
return java.util.Arrays.toString((double[]) o);
} else if (o instanceof char[]) {
return java.util.Arrays.toString((char[]) o);
} else {
return java.util.Objects.toString(o);
}
}

private static String normalizeString(String s) {
boolean isArray = (s.startsWith("{") && s.endsWith("}")) || (s.startsWith("[") && s.endsWith("]"));
if (isArray) {
s = s.replace(" ", "")
.replace("'", "")
.replace("\"", "")
.replace("{", "[")
.replace("}", "]");
}

return s;
}

private static void printCheck(String result, String expect, boolean ok) {
// System.out.println();
// System.out.println("--->");

System.out.println("result: " + result);
System.out.println("expect: " + expect);

System.out.println();
if (ok) {
System.out.println("比较结果为: 正确(right)");
} else {
System.out.println("比较结果为: 错误(error)");
}

// System.out.println();
// System.out.println("<---");
}

public static void runTestCases(Class<?> clazz) {
java.lang.reflect.Method[] methods = clazz.getDeclaredMethods();
java.util.Arrays.sort(methods, (o1, o2) -> {
return o1.getName().compareTo(o2.getName());
});
for (java.lang.reflect.Method method : methods) {
if (method.getName().startsWith("test")) {
System.out.println(String.format("--- %s --->", method.getName()));

Object object = null;
try {
object = method.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println(String.format("<--- %s ---", method.getName()));

if (object instanceof Boolean) {
Boolean ok = (Boolean) object;
if (!ok) {
break;
}
} else {
throw new RuntimeException(String.format("测试用例方法%s的返回值需要为布尔类型", method.getName()));
}
}
}
}

public static Object[] toArray(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0];
}

return list.toArray();
}

public static Object[][] toArrays(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0][0];
}

Object[][] arrays = new Object[list.size()][];
for (int i = 0; i < list.size(); i++) {
arrays[i] = toArray(list.get(i));
}

return arrays;
}

@SuppressWarnings("unchecked")
public static <T> T[] genArray(Class<T> clazz, int length) {
return (T[]) java.lang.reflect.Array.newInstance(clazz, length);
}

@SuppressWarnings("unchecked")
public static <T> T[][] genArrays(Class<T> clazz, int rows, int cols) {
T[] array = genArray(clazz, 0);

T[][] arrays = (T[][]) genArray(array.getClass(), rows);
for (int i = 0; i < arrays.length; i++) {
arrays[i] = genArray(clazz, cols);
}

return arrays;
}

public static <T> T[] toArray(java.util.List<T> list, Class<T> clazz) {
if (list == null || list.isEmpty()) {
return genArray(clazz, 0);
}

T[] array = genArray(clazz, list.size());
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}

return array;
}

public static <T> T[][] toArrays(java.util.List<java.util.List<T>> lists, Class<T> clazz) {
if (lists == null || lists.isEmpty()) {
return genArrays(clazz, 0, 0);
}

T[][] arrays = genArrays(clazz, lists.size(), 0);
for (int i = 0; i < lists.size(); i++) {
arrays[i] = toArray(lists.get(i), clazz);
}

return arrays;
}

public static <T> java.util.List<T> toList(T[] array) {
return java.util.Arrays.asList(array);
}

public static <T> java.util.List<java.util.List<T>> toLists(T[][] arrays) {
java.util.List<java.util.List<T>> lists = new java.util.ArrayList<>();
for (T[] array : arrays) {
lists.add(toList(array));
}

return lists;
}
}
}

二叉搜索树中第K小的元素

题目描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
给定一个二叉搜索树的根节点 root ,和一个整数 k ,请你设计一个算法查找其中第 k 个最小元素(从 1 开始计数)。



示例 1:

输入:root = [3,1,4,null,2], k = 1
输出:1
示例 2:

输入:root = [5,3,6,2,4,null,null,1], k = 3
输出:3




提示:

树中的节点数为 n 。
1 <= k <= n <= 104
0 <= Node.val <= 104


进阶:如果二叉搜索树经常被修改(插入/删除操作)并且你需要频繁地查找第 k 小的值,你将如何优化算法?

题目解答

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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
public class Solution {
private int v = 0;
private int c = 0;

public int kthSmallest(TreeNode root, int k) {
if (root == null) {
return 0;
}

if (c == k) {
return v;
}

kthSmallest(root.left, k);

// 中序遍历时处理结点
c++;
if (c == k) {
v = root.val;

return v;
}

kthSmallest(root.right, k);

return v;
}

static class TreeNode {
int val;
TreeNode left;
TreeNode right;

TreeNode() {
}

TreeNode(int val) {
this.val = val;
}

TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}

public static TreeNode genTree(Integer[] array) {
if (array.length == 0) {
return null;
}

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
TreeNode root = new TreeNode(array[0]);
queue.offer(root);

Integer v = null;
int i = 1;
while (i < array.length) {
TreeNode node = queue.poll();

TreeNode left = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;
TreeNode right = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;

// 数组中不包含空节点的子节点的写法(不标准的完全二叉树含空节点的层次遍历)
node.left = left;
node.right = right;
if (left != null) {
queue.offer(left);
}
if (right != null) {
queue.offer(right);
}

// 数组中包含空节点的子节点的写法(标准的完全二叉树含空节点的层次遍历)
// if (node != null) {
// node.left = left;
// node.right = right;
// }
// queue.offer(left);
// queue.offer(right);
}

return root;
}

public static Integer[] toArray(TreeNode root) {
if (root == null) {
return new Integer[0];
}

java.util.LinkedList<Integer> list = new java.util.LinkedList<>();

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
boolean hasValidNode = false;

int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();

if (node != null) {
list.add(node.val);

queue.offer(node.left);
queue.offer(node.right);

if (!hasValidNode) {
hasValidNode = node.left != null || node.right != null;
}
} else {
list.add(null);
}
}

if (!hasValidNode) {
// while (!queue.isEmpty()) {
// queue.poll();
// }

break;
}
}

while (!list.isEmpty() && list.get(list.size() - 1) == null) {
list.remove(list.size() - 1);
}

return list.toArray(new Integer[0]);
}
}
}

class TestMain {

public static void main(String[] args) {
TestUtils.runTestCases(TestCase.class);
}

public static class TestCase {

public static boolean testCase1() {
Integer[] nums = { 3, 1, 4, null, 2 };
int k = 1;

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
int result = new Solution().kthSmallest(tree, k);
int expect = 1;

return TestUtils.check(result, expect);
}

public static boolean testCase2() {
Integer[] nums = { 5, 3, 6, 2, 4, null, null, 1 };
int k = 3;

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
int result = new Solution().kthSmallest(tree, k);
int expect = 3;

return TestUtils.check(result, expect);
}
}

public static class TestUtils {

public static boolean check(Object result, Object expect) {
result = normalizeObject(result);
expect = normalizeObject(expect);
boolean ok = java.util.Objects.deepEquals(result, expect);
printCheck(toString(result), toString(expect), ok);
return ok;
}

public static boolean check(Object result, String expect) {
boolean ok = java.util.Objects.equals(normalizeString(toString(result)),
normalizeString(toString(expect)));
printCheck(normalizeString(toString(result)), normalizeString(toString(expect)), ok);
return ok;
}

private static Object normalizeObject(Object o) {
if (o instanceof java.util.List) {
java.util.List<?> list = (java.util.List<?>) o;
if (list != null && !list.isEmpty() && list.get(0) instanceof java.util.List) {
o = toArrays(list);
} else {
o = toArray(list);
}
}

return o;
}

private static String toString(Object o) {
if (o instanceof Object[]) {
return java.util.Arrays.deepToString((Object[]) o);
} else if (o instanceof int[]) {
return java.util.Arrays.toString((int[]) o);
} else if (o instanceof double[]) {
return java.util.Arrays.toString((double[]) o);
} else if (o instanceof char[]) {
return java.util.Arrays.toString((char[]) o);
} else {
return java.util.Objects.toString(o);
}
}

private static String normalizeString(String s) {
boolean isArray = (s.startsWith("{") && s.endsWith("}")) || (s.startsWith("[") && s.endsWith("]"));
if (isArray) {
s = s.replace(" ", "")
.replace("'", "")
.replace("\"", "")
.replace("{", "[")
.replace("}", "]");
}

return s;
}

private static void printCheck(String result, String expect, boolean ok) {
// System.out.println();
// System.out.println("--->");

System.out.println("result: " + result);
System.out.println("expect: " + expect);

System.out.println();
if (ok) {
System.out.println("比较结果为: 正确(right)");
} else {
System.out.println("比较结果为: 错误(error)");
}

// System.out.println();
// System.out.println("<---");
}

public static void runTestCases(Class<?> clazz) {
java.lang.reflect.Method[] methods = clazz.getDeclaredMethods();
java.util.Arrays.sort(methods, (o1, o2) -> {
return o1.getName().compareTo(o2.getName());
});
for (java.lang.reflect.Method method : methods) {
if (method.getName().startsWith("test")) {
System.out.println(String.format("--- %s --->", method.getName()));

Object object = null;
try {
object = method.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println(String.format("<--- %s ---", method.getName()));

if (object instanceof Boolean) {
Boolean ok = (Boolean) object;
if (!ok) {
break;
}
} else {
throw new RuntimeException(String.format("测试用例方法%s的返回值需要为布尔类型", method.getName()));
}
}
}
}

public static Object[] toArray(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0];
}

return list.toArray();
}

public static Object[][] toArrays(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0][0];
}

Object[][] arrays = new Object[list.size()][];
for (int i = 0; i < list.size(); i++) {
arrays[i] = toArray(list.get(i));
}

return arrays;
}

@SuppressWarnings("unchecked")
public static <T> T[] genArray(Class<T> clazz, int length) {
return (T[]) java.lang.reflect.Array.newInstance(clazz, length);
}

@SuppressWarnings("unchecked")
public static <T> T[][] genArrays(Class<T> clazz, int rows, int cols) {
T[] array = genArray(clazz, 0);

T[][] arrays = (T[][]) genArray(array.getClass(), rows);
for (int i = 0; i < arrays.length; i++) {
arrays[i] = genArray(clazz, cols);
}

return arrays;
}

public static <T> T[] toArray(java.util.List<T> list, Class<T> clazz) {
if (list == null || list.isEmpty()) {
return genArray(clazz, 0);
}

T[] array = genArray(clazz, list.size());
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}

return array;
}

public static <T> T[][] toArrays(java.util.List<java.util.List<T>> lists, Class<T> clazz) {
if (lists == null || lists.isEmpty()) {
return genArrays(clazz, 0, 0);
}

T[][] arrays = genArrays(clazz, lists.size(), 0);
for (int i = 0; i < lists.size(); i++) {
arrays[i] = toArray(lists.get(i), clazz);
}

return arrays;
}

public static <T> java.util.List<T> toList(T[] array) {
return java.util.Arrays.asList(array);
}

public static <T> java.util.List<java.util.List<T>> toLists(T[][] arrays) {
java.util.List<java.util.List<T>> lists = new java.util.ArrayList<>();
for (T[] array : arrays) {
lists.add(toList(array));
}

return lists;
}
}
}

进阶解法

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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
import java.util.Deque;
import java.util.LinkedList;

public class Solution {
public int kthSmallest(TreeNode root, int k) {
if (root == null) {
return 0;
}

int c = 0;

Deque<TreeNode> stack = new LinkedList<>();

TreeNode p = root;
while (p != null || !stack.isEmpty()) {
if (p != null) {

stack.push(p);

p = p.left;
} else {
p = stack.pop();

if (++c == k) {
return p.val;
}

p = p.right;
}
}

return 0;
}

static class TreeNode {
int val;
TreeNode left;
TreeNode right;

TreeNode() {
}

TreeNode(int val) {
this.val = val;
}

TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}

public static TreeNode genTree(Integer[] array) {
if (array.length == 0) {
return null;
}

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
TreeNode root = new TreeNode(array[0]);
queue.offer(root);

Integer v = null;
int i = 1;
while (i < array.length) {
TreeNode node = queue.poll();

TreeNode left = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;
TreeNode right = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;

// 数组中不包含空节点的子节点的写法(不标准的完全二叉树含空节点的层次遍历)
node.left = left;
node.right = right;
if (left != null) {
queue.offer(left);
}
if (right != null) {
queue.offer(right);
}

// 数组中包含空节点的子节点的写法(标准的完全二叉树含空节点的层次遍历)
// if (node != null) {
// node.left = left;
// node.right = right;
// }
// queue.offer(left);
// queue.offer(right);
}

return root;
}

public static Integer[] toArray(TreeNode root) {
if (root == null) {
return new Integer[0];
}

java.util.LinkedList<Integer> list = new java.util.LinkedList<>();

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
boolean hasValidNode = false;

int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();

if (node != null) {
list.add(node.val);

queue.offer(node.left);
queue.offer(node.right);

if (!hasValidNode) {
hasValidNode = node.left != null || node.right != null;
}
} else {
list.add(null);
}
}

if (!hasValidNode) {
// while (!queue.isEmpty()) {
// queue.poll();
// }

break;
}
}

while (!list.isEmpty() && list.get(list.size() - 1) == null) {
list.remove(list.size() - 1);
}

return list.toArray(new Integer[0]);
}
}
}

class TestMain {

public static void main(String[] args) {
TestUtils.runTestCases(TestCase.class);
}

public static class TestCase {

public static boolean testCase1() {
Integer[] nums = { 3, 1, 4, null, 2 };
int k = 1;

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
int result = new Solution().kthSmallest(tree, k);
int expect = 1;

return TestUtils.check(result, expect);
}

public static boolean testCase2() {
Integer[] nums = { 5, 3, 6, 2, 4, null, null, 1 };
int k = 3;

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
int result = new Solution().kthSmallest(tree, k);
int expect = 3;

return TestUtils.check(result, expect);
}
}

public static class TestUtils {

public static boolean check(Object result, Object expect) {
result = normalizeObject(result);
expect = normalizeObject(expect);
boolean ok = java.util.Objects.deepEquals(result, expect);
printCheck(toString(result), toString(expect), ok);
return ok;
}

public static boolean check(Object result, String expect) {
boolean ok = java.util.Objects.equals(normalizeString(toString(result)),
normalizeString(toString(expect)));
printCheck(normalizeString(toString(result)), normalizeString(toString(expect)), ok);
return ok;
}

private static Object normalizeObject(Object o) {
if (o instanceof java.util.List) {
java.util.List<?> list = (java.util.List<?>) o;
if (list != null && !list.isEmpty() && list.get(0) instanceof java.util.List) {
o = toArrays(list);
} else {
o = toArray(list);
}
}

return o;
}

private static String toString(Object o) {
if (o instanceof Object[]) {
return java.util.Arrays.deepToString((Object[]) o);
} else if (o instanceof int[]) {
return java.util.Arrays.toString((int[]) o);
} else if (o instanceof double[]) {
return java.util.Arrays.toString((double[]) o);
} else if (o instanceof char[]) {
return java.util.Arrays.toString((char[]) o);
} else {
return java.util.Objects.toString(o);
}
}

private static String normalizeString(String s) {
boolean isArray = (s.startsWith("{") && s.endsWith("}")) || (s.startsWith("[") && s.endsWith("]"));
if (isArray) {
s = s.replace(" ", "")
.replace("'", "")
.replace("\"", "")
.replace("{", "[")
.replace("}", "]");
}

return s;
}

private static void printCheck(String result, String expect, boolean ok) {
// System.out.println();
// System.out.println("--->");

System.out.println("result: " + result);
System.out.println("expect: " + expect);

System.out.println();
if (ok) {
System.out.println("比较结果为: 正确(right)");
} else {
System.out.println("比较结果为: 错误(error)");
}

// System.out.println();
// System.out.println("<---");
}

public static void runTestCases(Class<?> clazz) {
java.lang.reflect.Method[] methods = clazz.getDeclaredMethods();
java.util.Arrays.sort(methods, (o1, o2) -> {
return o1.getName().compareTo(o2.getName());
});
for (java.lang.reflect.Method method : methods) {
if (method.getName().startsWith("test")) {
System.out.println(String.format("--- %s --->", method.getName()));

Object object = null;
try {
object = method.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println(String.format("<--- %s ---", method.getName()));

if (object instanceof Boolean) {
Boolean ok = (Boolean) object;
if (!ok) {
break;
}
} else {
throw new RuntimeException(String.format("测试用例方法%s的返回值需要为布尔类型", method.getName()));
}
}
}
}

public static Object[] toArray(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0];
}

return list.toArray();
}

public static Object[][] toArrays(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0][0];
}

Object[][] arrays = new Object[list.size()][];
for (int i = 0; i < list.size(); i++) {
arrays[i] = toArray(list.get(i));
}

return arrays;
}

@SuppressWarnings("unchecked")
public static <T> T[] genArray(Class<T> clazz, int length) {
return (T[]) java.lang.reflect.Array.newInstance(clazz, length);
}

@SuppressWarnings("unchecked")
public static <T> T[][] genArrays(Class<T> clazz, int rows, int cols) {
T[] array = genArray(clazz, 0);

T[][] arrays = (T[][]) genArray(array.getClass(), rows);
for (int i = 0; i < arrays.length; i++) {
arrays[i] = genArray(clazz, cols);
}

return arrays;
}

public static <T> T[] toArray(java.util.List<T> list, Class<T> clazz) {
if (list == null || list.isEmpty()) {
return genArray(clazz, 0);
}

T[] array = genArray(clazz, list.size());
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}

return array;
}

public static <T> T[][] toArrays(java.util.List<java.util.List<T>> lists, Class<T> clazz) {
if (lists == null || lists.isEmpty()) {
return genArrays(clazz, 0, 0);
}

T[][] arrays = genArrays(clazz, lists.size(), 0);
for (int i = 0; i < lists.size(); i++) {
arrays[i] = toArray(lists.get(i), clazz);
}

return arrays;
}

public static <T> java.util.List<T> toList(T[] array) {
return java.util.Arrays.asList(array);
}

public static <T> java.util.List<java.util.List<T>> toLists(T[][] arrays) {
java.util.List<java.util.List<T>> lists = new java.util.ArrayList<>();
for (T[] array : arrays) {
lists.add(toList(array));
}

return lists;
}
}
}

其他解法

解法1

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
class Solution {
public int kthSmallest(TreeNode root, int k) {
MyBst bst = new MyBst(root);
return bst.kthSmallest(k);
}
}

class MyBst {
TreeNode root;
Map<TreeNode, Integer> nodeNum;

public MyBst(TreeNode root) {
this.root = root;
this.nodeNum = new HashMap<TreeNode, Integer>();
countNodeNum(root);
}

// 返回二叉搜索树中第k小的元素
public int kthSmallest(int k) {
TreeNode node = root;
while (node != null) {
int left = getNodeNum(node.left);
if (left < k - 1) {
node = node.right;
k -= left + 1;
} else if (left == k - 1) {
break;
} else {
node = node.left;
}
}
return node.val;
}

// 统计以node为根结点的子树的结点数
private int countNodeNum(TreeNode node) {
if (node == null) {
return 0;
}
nodeNum.put(node, 1 + countNodeNum(node.left) + countNodeNum(node.right));
return nodeNum.get(node);
}

// 获取以node为根结点的子树的结点数
private int getNodeNum(TreeNode node) {
return nodeNum.getOrDefault(node, 0);
}
}

验证二叉搜索树

题目描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。

有效 二叉搜索树定义如下:

节点的左子树只包含 小于 当前节点的数。
节点的右子树只包含 大于 当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。


示例 1:

输入:root = [2,1,3]
输出:true
示例 2:

输入:root = [5,1,4,null,null,3,6]
输出:false
解释:根节点的值是 5 ,但是右子节点的值是 4 。


提示:

树中节点数目范围在[1, 104] 内
-231 <= Node.val <= 231 - 1

题目解答

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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
public class Solution {
private TreeNode preNode = null;

public boolean isValidBST(TreeNode root) {
if (root == null) {
return true;
}

if (!isValidBST(root.left)) {
return false;
}

// 中序遍历时处理结点
if (preNode != null && root.val <= preNode.val) {
return false;
}

preNode = root;

if (!isValidBST(root.right)) {
return false;
}

return true;
}

static class TreeNode {
int val;
TreeNode left;
TreeNode right;

TreeNode() {
}

TreeNode(int val) {
this.val = val;
}

TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}

public static TreeNode genTree(Integer[] array) {
if (array.length == 0) {
return null;
}

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
TreeNode root = new TreeNode(array[0]);
queue.offer(root);

Integer v = null;
int i = 1;
while (i < array.length) {
TreeNode node = queue.poll();

TreeNode left = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;
TreeNode right = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;

// 数组中不包含空节点的子节点的写法(不标准的完全二叉树含空节点的层次遍历)
node.left = left;
node.right = right;
if (left != null) {
queue.offer(left);
}
if (right != null) {
queue.offer(right);
}

// 数组中包含空节点的子节点的写法(标准的完全二叉树含空节点的层次遍历)
// if (node != null) {
// node.left = left;
// node.right = right;
// }
// queue.offer(left);
// queue.offer(right);
}

return root;
}

public static Integer[] toArray(TreeNode root) {
if (root == null) {
return new Integer[0];
}

java.util.LinkedList<Integer> list = new java.util.LinkedList<>();

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
boolean hasValidNode = false;

int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();

if (node != null) {
list.add(node.val);

queue.offer(node.left);
queue.offer(node.right);

if (!hasValidNode) {
hasValidNode = node.left != null || node.right != null;
}
} else {
list.add(null);
}
}

if (!hasValidNode) {
// while (!queue.isEmpty()) {
// queue.poll();
// }

break;
}
}

while (!list.isEmpty() && list.get(list.size() - 1) == null) {
list.remove(list.size() - 1);
}

return list.toArray(new Integer[0]);
}
}
}

class TestMain {

public static void main(String[] args) {
TestUtils.runTestCases(TestCase.class);
}

public static class TestCase {

public static boolean testCase1() {
Integer[] nums = { 2, 1, 3 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
boolean result = new Solution().isValidBST(tree);
boolean expect = true;

return TestUtils.check(result, expect);
}

public static boolean testCase2() {
Integer[] nums = { 2, null, 3 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
boolean result = new Solution().isValidBST(tree);
boolean expect = true;

return TestUtils.check(result, expect);
}

public static boolean testCase3() {
Integer[] nums = { 5, 1, 4, null, null, 3, 6 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
boolean result = new Solution().isValidBST(tree);
boolean expect = false;

return TestUtils.check(result, expect);
}

public static boolean testCase4() {
Integer[] nums = { 5, 4, 6, null, null, 3, 7 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
boolean result = new Solution().isValidBST(tree);
boolean expect = false;

return TestUtils.check(result, expect);
}

public static boolean testCase5() {
Integer[] nums = { 120, 70, 140, 50, 100, 130, 160, 20, 55, 75, 110, 119, 135, 150, 200 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
boolean result = new Solution().isValidBST(tree);
boolean expect = false;

return TestUtils.check(result, expect);
}
}

public static class TestUtils {

public static boolean check(Object result, Object expect) {
result = normalizeObject(result);
expect = normalizeObject(expect);
boolean ok = java.util.Objects.deepEquals(result, expect);
printCheck(toString(result), toString(expect), ok);
return ok;
}

public static boolean check(Object result, String expect) {
boolean ok = java.util.Objects.equals(normalizeString(toString(result)),
normalizeString(toString(expect)));
printCheck(normalizeString(toString(result)), normalizeString(toString(expect)), ok);
return ok;
}

private static Object normalizeObject(Object o) {
if (o instanceof java.util.List) {
java.util.List<?> list = (java.util.List<?>) o;
if (list != null && !list.isEmpty() && list.get(0) instanceof java.util.List) {
o = toArrays(list);
} else {
o = toArray(list);
}
}

return o;
}

private static String toString(Object o) {
if (o instanceof Object[]) {
return java.util.Arrays.deepToString((Object[]) o);
} else if (o instanceof int[]) {
return java.util.Arrays.toString((int[]) o);
} else if (o instanceof double[]) {
return java.util.Arrays.toString((double[]) o);
} else if (o instanceof char[]) {
return java.util.Arrays.toString((char[]) o);
} else {
return java.util.Objects.toString(o);
}
}

private static String normalizeString(String s) {
boolean isArray = (s.startsWith("{") && s.endsWith("}")) || (s.startsWith("[") && s.endsWith("]"));
if (isArray) {
s = s.replace(" ", "")
.replace("'", "")
.replace("\"", "")
.replace("{", "[")
.replace("}", "]");
}

return s;
}

private static void printCheck(String result, String expect, boolean ok) {
// System.out.println();
// System.out.println("--->");

System.out.println("result: " + result);
System.out.println("expect: " + expect);

System.out.println();
if (ok) {
System.out.println("比较结果为: 正确(right)");
} else {
System.out.println("比较结果为: 错误(error)");
}

// System.out.println();
// System.out.println("<---");
}

public static void runTestCases(Class<?> clazz) {
java.lang.reflect.Method[] methods = clazz.getDeclaredMethods();
java.util.Arrays.sort(methods, (o1, o2) -> {
return o1.getName().compareTo(o2.getName());
});
for (java.lang.reflect.Method method : methods) {
if (method.getName().startsWith("test")) {
System.out.println(String.format("--- %s --->", method.getName()));

Object object = null;
try {
object = method.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println(String.format("<--- %s ---", method.getName()));

if (object instanceof Boolean) {
Boolean ok = (Boolean) object;
if (!ok) {
break;
}
} else {
throw new RuntimeException(String.format("测试用例方法%s的返回值需要为布尔类型", method.getName()));
}
}
}
}

public static Object[] toArray(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0];
}

return list.toArray();
}

public static Object[][] toArrays(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0][0];
}

Object[][] arrays = new Object[list.size()][];
for (int i = 0; i < list.size(); i++) {
arrays[i] = toArray(list.get(i));
}

return arrays;
}

@SuppressWarnings("unchecked")
public static <T> T[] genArray(Class<T> clazz, int length) {
return (T[]) java.lang.reflect.Array.newInstance(clazz, length);
}

@SuppressWarnings("unchecked")
public static <T> T[][] genArrays(Class<T> clazz, int rows, int cols) {
T[] array = genArray(clazz, 0);

T[][] arrays = (T[][]) genArray(array.getClass(), rows);
for (int i = 0; i < arrays.length; i++) {
arrays[i] = genArray(clazz, cols);
}

return arrays;
}

public static <T> T[] toArray(java.util.List<T> list, Class<T> clazz) {
if (list == null || list.isEmpty()) {
return genArray(clazz, 0);
}

T[] array = genArray(clazz, list.size());
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}

return array;
}

public static <T> T[][] toArrays(java.util.List<java.util.List<T>> lists, Class<T> clazz) {
if (lists == null || lists.isEmpty()) {
return genArrays(clazz, 0, 0);
}

T[][] arrays = genArrays(clazz, lists.size(), 0);
for (int i = 0; i < lists.size(); i++) {
arrays[i] = toArray(lists.get(i), clazz);
}

return arrays;
}

public static <T> java.util.List<T> toList(T[] array) {
return java.util.Arrays.asList(array);
}

public static <T> java.util.List<java.util.List<T>> toLists(T[][] arrays) {
java.util.List<java.util.List<T>> lists = new java.util.ArrayList<>();
for (T[] array : arrays) {
lists.add(toList(array));
}

return lists;
}
}
}

进阶解法

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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
import java.util.Deque;
import java.util.LinkedList;

public class Solution {
public boolean isValidBST(TreeNode root) {
TreeNode preNode = null;

Deque<TreeNode> stack = new LinkedList<>();

TreeNode p = root;
while (p != null || !stack.isEmpty()) {
if (p != null) {

stack.push(p);

p = p.left;
} else {
p = stack.pop();

if (preNode != null && p.val <= preNode.val) {
return false;
}

preNode = p;

p = p.right;
}
}

return true;
}

static class TreeNode {
int val;
TreeNode left;
TreeNode right;

TreeNode() {
}

TreeNode(int val) {
this.val = val;
}

TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}

public static TreeNode genTree(Integer[] array) {
if (array.length == 0) {
return null;
}

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
TreeNode root = new TreeNode(array[0]);
queue.offer(root);

Integer v = null;
int i = 1;
while (i < array.length) {
TreeNode node = queue.poll();

TreeNode left = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;
TreeNode right = i < array.length && (v = array[i++]) != null ? new TreeNode(v) : null;

// 数组中不包含空节点的子节点的写法(不标准的完全二叉树含空节点的层次遍历)
node.left = left;
node.right = right;
if (left != null) {
queue.offer(left);
}
if (right != null) {
queue.offer(right);
}

// 数组中包含空节点的子节点的写法(标准的完全二叉树含空节点的层次遍历)
// if (node != null) {
// node.left = left;
// node.right = right;
// }
// queue.offer(left);
// queue.offer(right);
}

return root;
}

public static Integer[] toArray(TreeNode root) {
if (root == null) {
return new Integer[0];
}

java.util.LinkedList<Integer> list = new java.util.LinkedList<>();

java.util.Queue<TreeNode> queue = new java.util.LinkedList<>();
queue.offer(root);

while (!queue.isEmpty()) {
boolean hasValidNode = false;

int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();

if (node != null) {
list.add(node.val);

queue.offer(node.left);
queue.offer(node.right);

if (!hasValidNode) {
hasValidNode = node.left != null || node.right != null;
}
} else {
list.add(null);
}
}

if (!hasValidNode) {
// while (!queue.isEmpty()) {
// queue.poll();
// }

break;
}
}

while (!list.isEmpty() && list.get(list.size() - 1) == null) {
list.remove(list.size() - 1);
}

return list.toArray(new Integer[0]);
}
}
}

class TestMain {

public static void main(String[] args) {
TestUtils.runTestCases(TestCase.class);
}

public static class TestCase {

public static boolean testCase1() {
Integer[] nums = { 2, 1, 3 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
boolean result = new Solution().isValidBST(tree);
boolean expect = true;

return TestUtils.check(result, expect);
}

public static boolean testCase2() {
Integer[] nums = { 2, null, 3 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
boolean result = new Solution().isValidBST(tree);
boolean expect = true;

return TestUtils.check(result, expect);
}

public static boolean testCase3() {
Integer[] nums = { 5, 1, 4, null, null, 3, 6 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
boolean result = new Solution().isValidBST(tree);
boolean expect = false;

return TestUtils.check(result, expect);
}

public static boolean testCase4() {
Integer[] nums = { 5, 4, 6, null, null, 3, 7 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
boolean result = new Solution().isValidBST(tree);
boolean expect = false;

return TestUtils.check(result, expect);
}

public static boolean testCase5() {
Integer[] nums = { 120, 70, 140, 50, 100, 130, 160, 20, 55, 75, 110, 119, 135, 150, 200 };

Solution.TreeNode tree = Solution.TreeNode.genTree(nums);
boolean result = new Solution().isValidBST(tree);
boolean expect = false;

return TestUtils.check(result, expect);
}
}

public static class TestUtils {

public static boolean check(Object result, Object expect) {
result = normalizeObject(result);
expect = normalizeObject(expect);
boolean ok = java.util.Objects.deepEquals(result, expect);
printCheck(toString(result), toString(expect), ok);
return ok;
}

public static boolean check(Object result, String expect) {
boolean ok = java.util.Objects.equals(normalizeString(toString(result)),
normalizeString(toString(expect)));
printCheck(normalizeString(toString(result)), normalizeString(toString(expect)), ok);
return ok;
}

private static Object normalizeObject(Object o) {
if (o instanceof java.util.List) {
java.util.List<?> list = (java.util.List<?>) o;
if (list != null && !list.isEmpty() && list.get(0) instanceof java.util.List) {
o = toArrays(list);
} else {
o = toArray(list);
}
}

return o;
}

private static String toString(Object o) {
if (o instanceof Object[]) {
return java.util.Arrays.deepToString((Object[]) o);
} else if (o instanceof int[]) {
return java.util.Arrays.toString((int[]) o);
} else if (o instanceof double[]) {
return java.util.Arrays.toString((double[]) o);
} else if (o instanceof char[]) {
return java.util.Arrays.toString((char[]) o);
} else {
return java.util.Objects.toString(o);
}
}

private static String normalizeString(String s) {
boolean isArray = (s.startsWith("{") && s.endsWith("}")) || (s.startsWith("[") && s.endsWith("]"));
if (isArray) {
s = s.replace(" ", "")
.replace("'", "")
.replace("\"", "")
.replace("{", "[")
.replace("}", "]");
}

return s;
}

private static void printCheck(String result, String expect, boolean ok) {
// System.out.println();
// System.out.println("--->");

System.out.println("result: " + result);
System.out.println("expect: " + expect);

System.out.println();
if (ok) {
System.out.println("比较结果为: 正确(right)");
} else {
System.out.println("比较结果为: 错误(error)");
}

// System.out.println();
// System.out.println("<---");
}

public static void runTestCases(Class<?> clazz) {
java.lang.reflect.Method[] methods = clazz.getDeclaredMethods();
java.util.Arrays.sort(methods, (o1, o2) -> {
return o1.getName().compareTo(o2.getName());
});
for (java.lang.reflect.Method method : methods) {
if (method.getName().startsWith("test")) {
System.out.println(String.format("--- %s --->", method.getName()));

Object object = null;
try {
object = method.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println(String.format("<--- %s ---", method.getName()));

if (object instanceof Boolean) {
Boolean ok = (Boolean) object;
if (!ok) {
break;
}
} else {
throw new RuntimeException(String.format("测试用例方法%s的返回值需要为布尔类型", method.getName()));
}
}
}
}

public static Object[] toArray(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0];
}

return list.toArray();
}

public static Object[][] toArrays(Object o) {
java.util.List<?> list = (java.util.List<?>) o;
if (list == null || list.isEmpty()) {
return new Object[0][0];
}

Object[][] arrays = new Object[list.size()][];
for (int i = 0; i < list.size(); i++) {
arrays[i] = toArray(list.get(i));
}

return arrays;
}

@SuppressWarnings("unchecked")
public static <T> T[] genArray(Class<T> clazz, int length) {
return (T[]) java.lang.reflect.Array.newInstance(clazz, length);
}

@SuppressWarnings("unchecked")
public static <T> T[][] genArrays(Class<T> clazz, int rows, int cols) {
T[] array = genArray(clazz, 0);

T[][] arrays = (T[][]) genArray(array.getClass(), rows);
for (int i = 0; i < arrays.length; i++) {
arrays[i] = genArray(clazz, cols);
}

return arrays;
}

public static <T> T[] toArray(java.util.List<T> list, Class<T> clazz) {
if (list == null || list.isEmpty()) {
return genArray(clazz, 0);
}

T[] array = genArray(clazz, list.size());
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}

return array;
}

public static <T> T[][] toArrays(java.util.List<java.util.List<T>> lists, Class<T> clazz) {
if (lists == null || lists.isEmpty()) {
return genArrays(clazz, 0, 0);
}

T[][] arrays = genArrays(clazz, lists.size(), 0);
for (int i = 0; i < lists.size(); i++) {
arrays[i] = toArray(lists.get(i), clazz);
}

return arrays;
}

public static <T> java.util.List<T> toList(T[] array) {
return java.util.Arrays.asList(array);
}

public static <T> java.util.List<java.util.List<T>> toLists(T[][] arrays) {
java.util.List<java.util.List<T>> lists = new java.util.ArrayList<>();
for (T[] array : arrays) {
lists.add(toList(array));
}

return lists;
}
}
}

实现哈夫曼树

题目描述

1
实现哈夫曼树

题目解答

1
//

TODO:实现哈夫曼树

实现字典树

题目描述

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
Trie(发音类似 "try")或者说 前缀树 是一种树形数据结构,用于高效地存储和检索字符串数据集中的键。这一数据结构有相当多的应用情景,例如自动补完和拼写检查。

请你实现 Trie 类:

Trie() 初始化前缀树对象。
void insert(String word) 向前缀树中插入字符串 word 。
boolean search(String word) 如果字符串 word 在前缀树中,返回 true(即,在检索之前已经插入);否则,返回 false 。
boolean startsWith(String prefix) 如果之前已经插入的字符串 word 的前缀之一为 prefix ,返回 true ;否则,返回 false 。


示例:

输入
["Trie", "insert", "search", "search", "startsWith", "insert", "search"]
[[], ["apple"], ["apple"], ["app"], ["app"], ["app"], ["app"]]
输出
[null, null, true, false, true, null, true]

解释
Trie trie = new Trie();
trie.insert("apple");
trie.search("apple"); // 返回 True
trie.search("app"); // 返回 False
trie.startsWith("app"); // 返回 True
trie.insert("app");
trie.search("app"); // 返回 True


提示:

1 <= word.length, prefix.length <= 2000
word 和 prefix 仅由小写英文字母组成
insert、search 和 startsWith 调用次数 总计 不超过 3 * 104 次

题目解答

1
//

TODO:实现字典树

添加与搜索单词-数据结构设计

题目描述

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
请你设计一个数据结构,支持 添加新单词 和 查找字符串是否与任何先前添加的字符串匹配 。

实现词典类 WordDictionary :

WordDictionary() 初始化词典对象
void addWord(word) 将 word 添加到数据结构中,之后可以对它进行匹配
bool search(word) 如果数据结构中存在字符串与 word 匹配,则返回 true ;否则,返回 false 。word 中可能包含一些 '.' ,每个 . 都可以表示任何一个字母。


示例:

输入:
["WordDictionary","addWord","addWord","addWord","search","search","search","search"]
[[],["bad"],["dad"],["mad"],["pad"],["bad"],[".ad"],["b.."]]
输出:
[null,null,null,null,false,true,true,true]

解释:
WordDictionary wordDictionary = new WordDictionary();
wordDictionary.addWord("bad");
wordDictionary.addWord("dad");
wordDictionary.addWord("mad");
wordDictionary.search("pad"); // 返回 False
wordDictionary.search("bad"); // 返回 True
wordDictionary.search(".ad"); // 返回 True
wordDictionary.search("b.."); // 返回 True


提示:

1 <= word.length <= 25
addWord 中的 word 由小写英文字母组成
search 中的 word 由 '.' 或小写英文字母组成
最多调用 104 次 addWord 和 search

题目解答

1
//

TODO:添加与搜索单词-数据结构设计

困难

二叉树中的最大路径和

题目描述

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
二叉树中的 路径 被定义为一条节点序列,序列中每对相邻节点之间都存在一条边。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点,且不一定经过根节点。

路径和 是路径中各节点值的总和。

给你一个二叉树的根节点 root ,返回其 最大路径和 。



示例 1:


输入:root = [1,2,3]
输出:6
解释:最优路径是 2 -> 1 -> 3 ,路径和为 2 + 1 + 3 = 6
示例 2:


输入:root = [-10,9,20,null,null,15,7]
输出:42
解释:最优路径是 15 -> 20 -> 7 ,路径和为 15 + 20 + 7 = 42


提示:

树中节点数目范围是 [1, 3 * 104]
-1000 <= Node.val <= 1000

题目解答

1
//

TODO:二叉树中的最大路径和

单词搜索II

题目描述

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
给定一个 m x n 二维字符网格 board 和一个单词(字符串)列表 words, 返回所有二维网格上的单词 。

单词必须按照字母顺序,通过 相邻的单元格 内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母在一个单词中不允许被重复使用。



示例 1:

输入:board = [["o","a","a","n"],["e","t","a","e"],["i","h","k","r"],["i","f","l","v"]], words = ["oath","pea","eat","rain"]
输出:["eat","oath"]
示例 2:

输入:board = [["a","b"],["c","d"]], words = ["abcb"]
输出:[]


提示:

m == board.length
n == board[i].length
1 <= m, n <= 12
board[i][j] 是一个小写英文字母
1 <= words.length <= 3 * 104
1 <= words[i].length <= 10
words[i] 由小写英文字母组成
words 中的所有字符串互不相同

题目解答

1
//

TODO:单词搜索II

只想买包辣条