题目
给定一个二叉树,找出其最小深度。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
说明: 叶子节点是指没有子节点的节点。
示例:
给定二叉树 [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回它的最小深度 2.
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-depth-of-binary-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题解
树的定义
首先,定义树节点结构 TreeNode。
// Definition for a binary tree node.
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
}
}
方法 1:递归
算法
最直接的思路就是递归。
我们用深度优先搜索来解决这个问题。
class Solution {
public int minDepth(TreeNode root) {
if (root == null) {
return 0;
}
if ((root.left == null) && (root.right == null)) {
return 1;
}
int min_depth = Integer.MAX_VALUE;
if (root.left != null) {
min_depth = Math.min(minDepth(root.left), min_depth);
}
if (root.right != null) {
min_depth = Math.min(minDepth(root.right), min_depth);
}
return min_depth + 1;
}
}
复杂度分析
时间复杂度:我们访问每个节点一次,时间复杂度为
O
(
N
)
O(N)
O(N) ,其中
N
N
N 是节点个数。
空间复杂度:最坏情况下,整棵树是非平衡的,例如每个节点都只有一个孩子,递归会调用
N
N
N (树的高度)次,因此栈的空间开销是
O
(
N
)
O(N)
O(N) 。但在最好情况下,树是完全平衡的,高度只有
log
(
N
)
\log(N)
log(N),因此在这种情况下空间复杂度只有
O
(
log
(
N
)
)
O(\log(N))
O(log(N)) 。
方法 2:深度优先搜索迭代
我们可以利用栈将上述解法中的递归变成迭代。
想法是对于每个节点,按照深度优先搜索的策略访问,同时在访问到叶子节点时更新最小深度。
我们从一个包含根节点的栈开始,当前深度为 1 。
然后开始迭代:弹出当前栈顶元素,将它的孩子节点压入栈中。当遇到叶子节点时更新最小深度。
import javafx.util.Pair;
class Solution {
public int minDepth(TreeNode root) {
LinkedList<Pair<TreeNode, Integer>> stack = new LinkedList<>();
if (root == null) {
return 0;
}
else {
stack.add(new Pair(root, 1));
}
int min_depth = Integer.MAX_VALUE;
while (!stack.isEmpty()) {
Pair<TreeNode, Integer> current = stack.pollLast();
root = current.getKey();
int current_depth = current.getValue();
if ((root.left == null) && (root.right == null)) {
min_depth = Math.min(min_depth, current_depth);
}
if (root.left != null) {
stack.add(new Pair(root.left, current_depth + 1));
}
if (root.right != null) {
stack.add(new Pair(root.right, current_depth + 1));
}
}
return min_depth;
}
}
复杂度分析
时间复杂度:每个节点恰好被访问一遍,复杂度为
O
(
N
)
O(N)
O(N)。
空间复杂度:最坏情况下我们会在栈中保存整棵树,此时空间复杂度为
O
(
N
)
O(N)
O(N)。
方法 3:宽度优先搜索迭代
深度优先搜索方法的缺陷是所有节点都必须访问到,以保证能够找到最小深度。因此复杂度是 O ( N ) O(N) O(N)。
一个优化的方法是利用宽度优先搜索,我们按照树的层次去迭代,第一个访问到的叶子就是最小深度的节点,这样就不要遍历所有的节点了。
import javafx.util.Pair;
class Solution {
public int minDepth(TreeNode root) {
LinkedList<Pair<TreeNode, Integer>> stack = new LinkedList<>();
if (root == null) {
return 0;
}
else {
stack.add(new Pair(root, 1));
}
int current_depth = 0;
while (!stack.isEmpty()) {
Pair<TreeNode, Integer> current = stack.poll();
root = current.getKey();
current_depth = current.getValue();
if ((root.left == null) && (root.right == null)) {
break;
}
if (root.left != null) {
stack.add(new Pair(root.left, current_depth + 1));
}
if (root.right != null) {
stack.add(new Pair(root.right, current_depth + 1));
}
}
return current_depth;
}
}
复杂度分析
时间复杂度:最坏情况下,这是一棵平衡树,我们需要按照树的层次一层一层的访问完所有节点,除去最后一层的节点。这样访问了
N
/
2
N/2
N/2 个节点,因此复杂度是
O
(
N
)
O(N)
O(N)。
空间复杂度:和时间复杂度相同,也是
O
(
N
)
O(N)
O(N)。
作者:LeetCode
链接:https://leetcode-cn.com/problems/two-sum/solution/er-cha-shu-de-zui-xiao-shen-du-by-leetcode/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
感想
参考104题,层次遍历迭代做了一次
执行用时 :2 ms, 在所有 Java 提交中击败了17.00%的用户
内存消耗 :36.8 MB, 在所有 Java 提交中击败了84.54%的用户
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public int minDepth(TreeNode root) {
int res = 0;
if(root==null) return res;
LinkedList<TreeNode> queue = new LinkedList<>();
queue.add(root);
res++;
TreeNode nextFirst = null;
TreeNode temp = null;
while(!queue.isEmpty()){
temp = queue.poll();
if(temp==nextFirst) {
nextFirst=null;
res++;
}
if(temp!=null){
if(temp.left==null && temp.right==null) return res;
queue.add(temp.left);
if(nextFirst==null && temp.left!=null) nextFirst = temp.left;
queue.add(temp.right);
if(nextFirst==null && temp.right!=null) nextFirst = temp.right;
}
}
return res;
}
}
然后试了一下递归:
执行用时 :1 ms, 在所有 Java 提交中击败了98.07%的用户
内存消耗 :36.6 MB, 在所有 Java 提交中击败了92.70%的用户
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public int minDepth(TreeNode root) {
if (root == null) {
return 0;
} else if(root.left==null&&root.right==null){
return 1;
} else if(root.left==null){
return minDepth(root.right)+1;
} else if(root.right==null){
return minDepth(root.left)+1;
} else {
return Math.min(minDepth(root.left), minDepth(root.right)) + 1;
}
}
}