Skip to content

Commit 0d25d0c

Browse files
committed
update codes
1 parent 7b5cb8c commit 0d25d0c

File tree

8 files changed

+434
-7
lines changed

8 files changed

+434
-7
lines changed

codes/data-structure/src/main/java/io/github/dunwu/ds/tree/BTree.java

Lines changed: 91 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
package io.github.dunwu.ds.tree;
22

3-
import java.util.ArrayList;
4-
import java.util.LinkedList;
5-
import java.util.List;
6-
import java.util.Queue;
3+
import java.util.*;
74

85
/**
96
* 二叉树
@@ -110,6 +107,48 @@ private static <T extends Comparable<T>> boolean isEquals(TreeNode<T> root1, Tre
110107
return isEquals(root1.left, root2.left) && isEquals(root1.right, root2.right);
111108
}
112109

110+
/**
111+
* 判断两颗二叉树的叶子节点是否相似
112+
*
113+
* @param tree1 {@link BTree}
114+
* @param tree2 {@link BTree}
115+
* @return true / false
116+
* @see <a href="https://leetcode-cn.com/problems/leaf-similar-trees/">叶子相似的树</a>
117+
*/
118+
public static <T extends Comparable<T>> boolean isLeafSimilar(final BTree<T> tree1, final BTree<T> tree2) {
119+
List<T> leafs1 = new LinkedList<>();
120+
List<T> leafs2 = new LinkedList<>();
121+
getLeafNodes(tree1, leafs1);
122+
getLeafNodes(tree2, leafs2);
123+
return Arrays.equals(leafs1.toArray(), leafs2.toArray());
124+
}
125+
126+
/**
127+
* 获取叶子节点
128+
*
129+
* @param tree {@link BTree}
130+
* @param leafs [出参]叶子节点列表{@link List}
131+
* @param <T> 元素类型
132+
*/
133+
public static <T extends Comparable<T>> void getLeafNodes(BTree<T> tree, List<T> leafs) {
134+
getLeafNodes(tree.root, leafs);
135+
}
136+
137+
/**
138+
* 获取叶子节点
139+
*
140+
* @param root {@link TreeNode}
141+
* @param leafs [出参]叶子节点列表{@link List}
142+
* @param <T> 元素类型
143+
*/
144+
private static <T extends Comparable<T>> void getLeafNodes(TreeNode<T> root, List<T> leafs) {
145+
if (root == null) { return; }
146+
147+
if (root.left == null && root.right == null) { leafs.add(root.value); }
148+
getLeafNodes(root.left, leafs);
149+
getLeafNodes(root.right, leafs);
150+
}
151+
113152
/**
114153
* 返回二叉树的最大深度
115154
*
@@ -136,6 +175,36 @@ private int maxDepth(TreeNode<T> root) {
136175
return Math.max(left, right) + 1;
137176
}
138177

178+
/**
179+
* 返回二叉树的最小深度
180+
*
181+
* @return 二叉树的最小深度
182+
*/
183+
public int minDepth() {
184+
return minDepth(this.root);
185+
}
186+
187+
/**
188+
* 采用递归方法获取二叉树的最小深度
189+
*
190+
* @param root 二叉树根节点,类型:{@link BTree#root}
191+
* @return 二叉树的最小深度
192+
* @see <a href="https://leetcode-cn.com/problems/minimum-depth-of-binary-tree/">二叉树的最小深度</a>
193+
*/
194+
private int minDepth(TreeNode<T> root) {
195+
if (root == null) { return 0; }
196+
197+
int left = minDepth(root.left);
198+
199+
int right = minDepth(root.right);
200+
201+
if (left == 0 || right == 0) {
202+
return left + right + 1;
203+
}
204+
205+
return Math.min(left, right) + 1;
206+
}
207+
139208
// ------------------------------------------------------------- 遍历元素
140209

141210
/**
@@ -144,7 +213,7 @@ private int maxDepth(TreeNode<T> root) {
144213
* @return {@link List<List<T>>}
145214
* @see <a href="https://leetcode-cn.com/problems/binary-tree-level-order-traversal-ii/">二叉树的层次遍历 II</a>
146215
*/
147-
public List<List<T>> levelOrderList() {
216+
public List<List<T>> levelOrderLists() {
148217
List<List<T>> lists = new ArrayList<>();
149218
if (root == null) { return lists; }
150219
Queue<TreeNode<T>> queue = new LinkedList<>();
@@ -163,6 +232,23 @@ public List<List<T>> levelOrderList() {
163232
return lists;
164233
}
165234

235+
public List<T> levelOrderList() {
236+
List<T> list = new ArrayList<>();
237+
if (root == null) { return list; }
238+
Queue<TreeNode<T>> queue = new LinkedList<>();
239+
queue.offer(root);
240+
while (!queue.isEmpty()) {
241+
int size = queue.size();
242+
for (int i = 0; i < size; i++) {
243+
TreeNode<T> node = queue.poll();
244+
list.add(node.value);
245+
if (node.left != null) { queue.offer(node.left); }
246+
if (node.right != null) { queue.offer(node.right); }
247+
}
248+
}
249+
return list;
250+
}
251+
166252
static class TreeNode<T extends Comparable<T>> {
167253

168254
T value;

codes/data-structure/src/test/java/io/github/dunwu/ds/tree/BTreeTests.java

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
package io.github.dunwu.ds.tree;
22

33
import org.junit.jupiter.api.Assertions;
4+
import org.junit.jupiter.api.DisplayName;
45
import org.junit.jupiter.api.Test;
56

67
import java.util.ArrayList;
78
import java.util.Arrays;
9+
import java.util.Collections;
810
import java.util.List;
911

1012
/**
@@ -14,12 +16,24 @@
1416
public class BTreeTests {
1517

1618
@Test
19+
@DisplayName("二叉树的最大深度")
1720
public void maxDepthTest() {
1821
BTree<Integer> tree = BTree.buildTree(1, 2, 3, 4, 5);
1922
Assertions.assertEquals(3, tree.maxDepth());
2023
}
2124

2225
@Test
26+
@DisplayName("二叉树的最小深度")
27+
public void minDepthTest() {
28+
BTree<Integer> tree = BTree.buildTree(3, 9, 20, null, null, 15, 7);
29+
Assertions.assertEquals(2, tree.minDepth());
30+
31+
tree = BTree.buildTree(1, 2);
32+
Assertions.assertEquals(2, tree.minDepth());
33+
}
34+
35+
@Test
36+
@DisplayName("判断两颗二叉树是否完全一致")
2337
public void isEqualsTest() {
2438
BTree<Integer> tree1 = BTree.buildTree(1, 2, 3);
2539
BTree<Integer> tree2 = BTree.buildTree(1, 2, 3);
@@ -31,13 +45,22 @@ public void isEqualsTest() {
3145
}
3246

3347
@Test
48+
@DisplayName("广度优先搜索(BFS)")
3449
public void levelOrderBottomTest() {
3550
BTree<Integer> tree = BTree.buildTree(3, 9, 20, null, null, 15, 7);
3651
List<List<Integer>> lists = new ArrayList<>();
37-
lists.add(Arrays.asList(3));
52+
lists.add(Collections.singletonList(3));
3853
lists.add(Arrays.asList(9, 20));
3954
lists.add(Arrays.asList(15, 7));
40-
Assertions.assertIterableEquals(lists, tree.levelOrderList());
55+
Assertions.assertIterableEquals(lists, tree.levelOrderLists());
56+
}
57+
58+
@Test
59+
@DisplayName("判断两颗二叉树的叶子节点是否相似")
60+
public void isLeafSimilarTest() {
61+
BTree<Integer> tree1 = BTree.buildTree(3, 5, 1, 6, 2, 9, 8, null, null, 7, 4);
62+
BTree<Integer> tree2 = BTree.buildTree(3, 5, 1, 6, 7, 4, 2, null, null, null, null, null, null, 9, 8);
63+
Assertions.assertTrue(BTree.isLeafSimilar(tree1, tree2));
4164
}
4265

4366
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package io.github.dunwu.ds.tree;
2+
3+
import java.util.LinkedList;
4+
import java.util.List;
5+
6+
/**
7+
* <code>二叉树的所有路径</code> 算法实现
8+
*
9+
* <pre>
10+
* 给定一个二叉树,返回所有从根节点到叶子节点的路径。
11+
*
12+
* 说明: 叶子节点是指没有子节点的节点。
13+
*
14+
* 示例:
15+
*
16+
* 输入:
17+
*
18+
* 1
19+
* / \
20+
* 2 3
21+
* \
22+
* 5
23+
*
24+
* 输出: ["1->2->5", "1->3"]
25+
*
26+
* 解释: 所有根节点到叶子节点的路径为: 1->2->5, 1->3
27+
* </pre>
28+
*
29+
* @see <a href="https://leetcode-cn.com/problems/binary-tree-paths/">二叉树的所有路径</a>
30+
*/
31+
public class BinaryTreePaths {
32+
33+
public static void main(String[] args) {
34+
BinaryTreePaths demo = new BinaryTreePaths();
35+
36+
TreeNode tree = TreeUtils.buildTree(1, 2, 3, 5);
37+
System.out.println("result = " + demo.binaryTreePaths(tree));
38+
}
39+
40+
public List<String> binaryTreePaths(TreeNode root) {
41+
List<String> paths = new LinkedList<>();
42+
recordPath(root, "", paths);
43+
return paths;
44+
}
45+
46+
private void recordPath(TreeNode node, String path, List<String> paths) {
47+
if (node != null) {
48+
path += node.val;
49+
if (node.left == null && node.right == null) {
50+
paths.add(path);
51+
} else {
52+
path += "->";
53+
recordPath(node.left, path, paths);
54+
recordPath(node.right, path, paths);
55+
}
56+
}
57+
}
58+
59+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package io.github.dunwu.ds.tree;
2+
3+
/**
4+
* <code>路径总和</code> 算法实现
5+
*
6+
* <pre>
7+
* 给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。
8+
*
9+
* 说明: 叶子节点是指没有子节点的节点。
10+
*
11+
* 示例: 
12+
* 给定如下二叉树,以及目标和 sum = 22,
13+
*
14+
* 5
15+
* / \
16+
* 4 8
17+
* / / \
18+
* 11 13 4
19+
* / \ \
20+
* 7 2 1
21+
* 返回 true, 因为存在目标和为 22 的根节点到叶子节点的路径 5->4->11->2。
22+
* </pre>
23+
*
24+
* @see <a href="https://leetcode-cn.com/problems/path-sum/">路径总和</a>
25+
*/
26+
public class HasPathSum {
27+
28+
public static void main(String[] args) {
29+
HasPathSum demo = new HasPathSum();
30+
31+
TreeNode tree = TreeUtils.buildTree(5, 4, 8, 11, null, 13, 4, 7, 2, null, null, null, null, null, 1);
32+
System.out.println("result = " + demo.hasPathSum(tree, 22));
33+
}
34+
35+
public boolean hasPathSum(TreeNode root, int sum) {
36+
if (root == null) { return false; }
37+
38+
sum -= root.val;
39+
40+
if (root.left == null && root.right == null) { return sum == 0; }
41+
42+
return hasPathSum(root.left, sum) || hasPathSum(root.right, sum);
43+
}
44+
45+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package io.github.dunwu.ds.tree;
2+
3+
/**
4+
* <code>翻转二叉树</code> 算法实现
5+
*
6+
* <pre>
7+
* 翻转一棵二叉树。
8+
*
9+
* 示例:
10+
*
11+
* 输入:
12+
*
13+
* 4
14+
* / \
15+
* 2 7
16+
* / \ / \
17+
* 1 3 6 9
18+
* 输出:
19+
*
20+
* 4
21+
* / \
22+
* 7 2
23+
* / \ / \
24+
* 9 6 3 1
25+
* 备注:
26+
* 这个问题是受到 Max Howell 的 原问题 启发的 :
27+
* </pre>
28+
*
29+
* @see <a href="https://leetcode-cn.com/problems/invert-binary-tree/">翻转二叉树</a>
30+
*/
31+
public class InvertTree {
32+
33+
public static void main(String[] args) {
34+
InvertTree demo = new InvertTree();
35+
36+
TreeNode tree = TreeUtils.buildTree(4, 2, 7, 1, 3, 6, 9);
37+
System.out.println("result = " + demo.invertTree(tree));
38+
}
39+
40+
public TreeNode invertTree(TreeNode root) {
41+
if (root == null) { return null; }
42+
43+
TreeNode right = invertTree(root.right);
44+
TreeNode left = invertTree(root.left);
45+
46+
root.left = right;
47+
root.right = left;
48+
return root;
49+
}
50+
51+
}

0 commit comments

Comments
 (0)