提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
在刷leetcode时,把二叉树最小深度和最大深度搞混了,在这里mark下
一、二叉树是什么?
二叉树(binary tree)是指树中节点的度不大于2的有序树,它是一种最简单且最重要的树
二、最大深度
1.利用深度优先搜索求其最大深度
代码如下(示例):
public int maxDepth(TreeNode root) {
if(root==null)
return 0;
int l=minDepth(root.left);
int r=minDepth(root.right);
return (l<r? l:r)+1;
}
总体的思路就是求出根节点的左右子树的深度,然后作比较,取最大的深度即可,在DFS时,对于每一个非叶子节点,我们只需要分别计算其左右子树的最小叶子节点深度。这样就将一个大问题转化为了小问题,可以递归地解决该问题。
2.利用深度优先搜索求其最小深度
代码如下(示例):
public int minDepth(TreeNode root) {
if(root==null)
return 0;
int l=minDepth(root.left);
int r=minDepth(root.right);
if(l==0||r==0)
return r+l+1;
return (l<r? l:r)+1;
}
与求最大深度不同点在于多了一个if判断,原因是什么呢?在这里举个例子,比如有一个二叉树是这样的,
该二叉树只有左子树,如果我们按照求最大深度的思路的话,对于1这个根节点,左子树求出的深度l为1,右子树求出的深度r为0,最后判断得出r<l,返回r+1=1,得出最小深度为1,显然这种思路是错的,因为我们忽略了根节点右子树为空的情况,针对于这种情况,我们可以判断,如果返回的l或者r有一个为0,既左右子树有一个为空,那么我们直接返回这个节点本身具有深度就可以,因为这个深度就是它的最小深度,利用l+r+1,得到这个节点具有的深度。
3.利用广度优先搜索求最小深度
代码如下(示例):
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class QueueNode{
TreeNode node;
int dep;
public QueueNode(TreeNode node,int dep){
this.node=node;
this.dep=dep;
}
}
class Solution {
public int minDepth(TreeNode root) {
if(root==null)
return 0;
Queue<QueueNode> queue=new LinkedList<QueueNode>();
queue.offer(new QueueNode(root,1));
while(!queue.isEmpty()){
QueueNode tempnode=queue.poll();
int tempdep=tempnode.dep;
TreeNode node=tempnode.node;
if(node.left==null&&node.right==null)
return tempdep;
if(node.left!=null){
queue.offer(new QueueNode(node.left,tempdep+1));
}
if(node.right!=null){
queue.offer(new QueueNode(node.right,tempdep+1));
}
}
return 0;
}
}
当我们找到一个叶子节点时,直接返回这个叶子节点的深度。广度优先搜索的性质保证了最先搜索到的叶子节点的深度一定最小
总结
1.利用DFS求最大深度与最小深度的时间复杂度都为O(N),N是树的节点数。空间复杂度O(H),H为树的深度。
2.利用BFS求最小深度时间复杂度为O(N),其中 N 是树的节点数。对每个节点访问一次。空间复杂度:O(N),其中 N 是树的节点数。空间复杂度主要取决于队列的开销,队列中的元素个数不会超过树的节点数。