Skip to content

Commit 400f0db

Browse files
committed
111
1 parent 7937201 commit 400f0db

File tree

3 files changed

+204
-3
lines changed

3 files changed

+204
-3
lines changed

SUMMARY.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@
102102
* [99. Recover Binary Search Tree](leetcode-99-Recover-Binary-Search-Tree.md)
103103
* [100. Same Tree](leetcode-100-Same-Tree.md)
104104
* [leetcode 100 斩!回顾](leetcode100斩回顾.md)
105-
* [101 题到 110](leetcode-101-200.md)
105+
* [101 题到 111](leetcode-101-200.md)
106106
* [101. Symmetric Tree](leetcode-101-Symmetric-Tree.md)
107107
* [102. Binary Tree Level Order Traversal](leetcode-102-Binary-Tree-Level-Order-Traversal.md)
108108
* [103. Binary Tree Zigzag Level Order Traversal](leetcode-103-Binary-Tree-Zigzag-Level-Order-Traversal.md)
@@ -112,4 +112,5 @@
112112
* [107. Binary Tree Level Order Traversal II](leetcode-107-Binary-Tree-Level-Order-TraversalII.md)
113113
* [108. Convert Sorted Array to Binary Search Tree](leetcode-108-Convert-Sorted-Array-to-Binary-Search-Tree.md)
114114
* [109. Convert Sorted List to Binary Search Tree](leetcode-109-Convert-Sorted-List-to-Binary-Search-Tree.md)
115-
* [110. Balanced Binary Tree](leetcode-110-Balanced-Binary-Tree.md)
115+
* [110. Balanced Binary Tree](leetcode-110-Balanced-Binary-Tree.md)
116+
* [111. Minimum Depth of Binary Tree](leetcode-111-Minimum-Depth-of-Binary-Tree.md)

leetcode-101-200.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,6 @@
1616

1717
<a href="leetcode-109-Convert-Sorted-List-to-Binary-Search-Tree.html">109. Convert Sorted List to Binary Search Tree</a>
1818

19-
<a href="leetcode-110-Balanced-Binary-Tree.html">110. Balanced Binary Tree</a>
19+
<a href="leetcode-110-Balanced-Binary-Tree.html">110. Balanced Binary Tree</a>
20+
21+
<a href="leetcode-111-Minimum-Depth-of-Binary-Tree.html">111. Minimum Depth of Binary Tree</a>
Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
# 题目描述(简单难度)
2+
3+
![](https://windliang.oss-cn-beijing.aliyuncs.com/111.jpg)
4+
5+
返回从根节点到叶子节点最小深度。
6+
7+
# 解法一 递归
8+
9+
[104 题](<https://leetcode.wang/leetcode-104-Maximum-Depth-of-Binary-Tree.html>) 有些像,当时是返回根节点到叶子节点的最大深度。记得当时的代码很简单。
10+
11+
```java
12+
public int maxDepth(TreeNode root) {
13+
if (root == null) {
14+
return 0;
15+
}
16+
return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
17+
}
18+
```
19+
20+
这道题是不是只要把`Math.max`,改成`Math.min`就够了。
21+
22+
```java
23+
public int minDepth(TreeNode root) {
24+
if (root == null) {
25+
return 0;
26+
}
27+
return Math.min(minDepth(root.left), minDepth(root.right)) + 1;
28+
}
29+
```
30+
31+
粗略的想一下,似乎很完美,比如题目给的例子
32+
33+
```java
34+
3
35+
/ \
36+
9 20
37+
/ \
38+
15 7
39+
```
40+
41+
根据代码走一遍,`root.left `返回 `1``root.right`返回 `2`,选较小的`1`,加上 `1` 返回结果`2`,完美符合结果。
42+
43+
但如果是下边的样子呢?
44+
45+
```java
46+
3
47+
/ \
48+
9 20
49+
/ / \
50+
8 15 7
51+
```
52+
53+
区别在于有一个子树的拥有一个孩子,另一个孩子为空。
54+
55+
这样利用上边的算法,当考虑`9`这个子树的时候,左孩子会返回`1`,由于它的右孩子为`null`,右孩子会返回`0`,选较小的`0`,加上 `1` 返回结果`1`给上一层。
56+
57+
也就是最顶层的`root.left `依旧得到了 `1`,但明显是不对的,对于左子树,应该是从 `9``8`,深度应该是 `2`
58+
59+
所以代码上需要修正这个算法,再想想题目要求是从根节点到叶节点,所以如果有一个子树的左孩子或者右孩子为`null`了,那就意味着这个方向不可能到达叶子节点了,所以就不要再用`Min`函数去判断了。
60+
61+
我对代码的修正如下:
62+
63+
```java
64+
public int minDepth(TreeNode root) {
65+
if (root == null) {
66+
return 0;
67+
}
68+
return minDepthHelper(root);
69+
70+
}
71+
72+
private int minDepthHelper(TreeNode root) {
73+
//到达叶子节点就返回 1
74+
if (root.left == null && root.right == null) {
75+
return 1;
76+
}
77+
//左孩子为空,只考虑右孩子的方向
78+
if (root.left == null) {
79+
return minDepthHelper(root.right) + 1;
80+
}
81+
//右孩子为空,只考虑左孩子的方向
82+
if (root.right == null) {
83+
return minDepthHelper(root.left) + 1;
84+
}
85+
//既有左孩子又有右孩子,那么就选一个较小的
86+
return Math.min(minDepthHelper(root.left), minDepthHelper(root.right)) + 1;
87+
}
88+
```
89+
90+
其实也是可以把两个函数合在一起的,参考[这里](<https://leetcode.com/problems/minimum-depth-of-binary-tree/discuss/36045/My-4-Line-java-solution>)
91+
92+
```java
93+
public int minDepth(TreeNode root) {
94+
if (root == null){
95+
return 0;
96+
}
97+
// 左孩子为空,只考虑右孩子的方向
98+
if (root.left == null) {
99+
return minDepth(root.right) + 1;
100+
}
101+
// 右孩子为空,只考虑左孩子的方向
102+
if (root.right == null) {
103+
return minDepth(root.left) + 1;
104+
}
105+
return Math.min(minDepth(root.left),minDepth(root.right)) + 1;
106+
}
107+
```
108+
109+
此外,还有一个想法,觉得不错,大家可以看看,参考[这里](<https://leetcode.com/problems/minimum-depth-of-binary-tree/discuss/36188/Very-easy-with-recursion-1ms-Java-solution>)
110+
111+
```java
112+
public int minDepth(TreeNode root) {
113+
if (root == null) {
114+
return 0;
115+
}
116+
if (root.left != null && root.right != null) {
117+
return Math.min(minDepth(root.left), minDepth(root.right)) + 1;
118+
} else {
119+
return Math.max(minDepth(root.left), minDepth(root.right)) + 1;
120+
}
121+
}
122+
```
123+
124+
当左孩子为空或者右孩子为空的时候,它就直接去选一个较大深度的,因为较小深度一定是为空的那个孩子,是我们不考虑的。
125+
126+
上边三个算法本质上其实是一样的,就是解决了一个孩子为空另一个不为空的问题,而对于[104 题](<https://leetcode.wang/leetcode-104-Maximum-Depth-of-Binary-Tree.html>) 没有出现这个问题,是因为我们选的是`max`,所以不用在意是否有一个为空。
127+
128+
# 解法二 BFS
129+
130+
[104 题](<https://leetcode.wang/leetcode-104-Maximum-Depth-of-Binary-Tree.html>) 也提供了`BFS`的方案,利用一个队列进行层次遍历,用一个 `level` 变量保存当前的深度,代码如下:
131+
132+
```java
133+
public int maxDepth(TreeNode root) {
134+
Queue<TreeNode> queue = new LinkedList<TreeNode>();
135+
List<List<Integer>> ans = new LinkedList<List<Integer>>();
136+
if (root == null)
137+
return 0;
138+
queue.offer(root);
139+
int level = 0;
140+
while (!queue.isEmpty()) {
141+
int levelNum = queue.size(); // 当前层元素的个数
142+
for (int i = 0; i < levelNum; i++) {
143+
TreeNode curNode = queue.poll();
144+
if (curNode != null) {
145+
if (curNode.left != null) {
146+
queue.offer(curNode.left);
147+
}
148+
if (curNode.right != null) {
149+
queue.offer(curNode.right);
150+
}
151+
}
152+
}
153+
level++;
154+
}
155+
return level;
156+
}
157+
158+
```
159+
160+
对于这道题就比较容易修改了,只要在 `for` 循环中判断当前是不是叶子节点,如果是的话,返回当前的 level 就可以了。此外要把`level`初始化改为`1`,因为如果只有一个根节点,它就是叶子节点,而在代码中,level 是在 `for`循环以后才`++`的,如果被提前结束的话,此时应该返回`1`
161+
162+
```java
163+
public int minDepth(TreeNode root) {
164+
Queue<TreeNode> queue = new LinkedList<TreeNode>();
165+
List<List<Integer>> ans = new LinkedList<List<Integer>>();
166+
if (root == null)
167+
return 0;
168+
queue.offer(root);
169+
/**********修改的地方*****************/
170+
int level = 1;
171+
/***********************************/
172+
while (!queue.isEmpty()) {
173+
int levelNum = queue.size(); // 当前层元素的个数
174+
for (int i = 0; i < levelNum; i++) {
175+
TreeNode curNode = queue.poll();
176+
if (curNode != null) {
177+
/**********修改的地方*****************/
178+
if (curNode.left == null && curNode.right == null) {
179+
return level;
180+
}
181+
/***********************************/
182+
if (curNode.left != null) {
183+
queue.offer(curNode.left);
184+
}
185+
if (curNode.right != null) {
186+
queue.offer(curNode.right);
187+
}
188+
}
189+
}
190+
level++;
191+
}
192+
return level;
193+
}
194+
```
195+
196+
#
197+
198+
[104 题](<https://leetcode.wang/leetcode-104-Maximum-Depth-of-Binary-Tree.html>) 题对比着考虑的话,只要找到这道题的不同之处,代码就很好写了。

0 commit comments

Comments
 (0)