算法_111-二叉树的最小深度

111. 二叉树的最小深度

题目:
111.二叉树的最小深度

方法一:深度优先搜索

思路及解法

首先可以想到使用深度优先搜索的方法,遍历整棵树,记录最小深度。
对于每一个非叶子节点,我们只需要分别计算其左右子树的最小叶子节点深度。这样就将一个大问题转化为了小问题,可以递归地解决该问题。

代码

int minDepth(struct TreeNode *root) {
    if (root == NULL) {
        return 0;
    }

    if (root->left == NULL && root->right == NULL) {
        return 1;
    }

    int min_depth = INT_MAX;
    if (root->left != NULL) {
        min_depth = fmin(minDepth(root->left), min_depth);
    }
    if (root->right != NULL) {
        min_depth = fmin(minDepth(root->right), min_depth);
    }

    return min_depth + 1;
}

补充知识:

int fmin(int a,int b); 求a,b中的最小值
int fmax(int a,int b);求a,b中的最大值

方法:
思路:

很多人写出的代码都不符合 1,2 这个测试用例,是因为没搞清楚题意
题目中说明:叶子节点是指没有子节点的节点,这句话的意思是 1 不是叶子节点
题目问的是到叶子节点的最短距离,所以所有返回结果为 1 当然不是这个结果
另外这道题的关键是搞清楚递归结束条件
叶子节点的定义是左孩子和右孩子都为 null 时叫做叶子节点
当 root 节点左右孩子都为空时,返回 1
当 root 节点左右孩子有一个为空时,返回不为空的孩子节点的深度
当 root 节点左右孩子都不为空时,返回左右孩子较小深度的节点值

第一版代码:

int minDepth(struct TreeNode *root) {
    if(root == NULL) 
        return 0;
    //这道题递归条件里分为三种情况
    //1.左孩子和有孩子都为空的情况,说明到达了叶子节点,直接返回1即可
    if(root->left == NULL && root->right == NULL)
        return 1;
    //2.如果左孩子和由孩子其中一个为空,那么需要返回比较大的那个孩子的深度        
    int m1 = minDepth(root->left);
    int m2 = minDepth(root->right);
    //这里其中一个节点为空,说明m1和m2有一个必然为0,所以可以返回m1 + m2 + 1;
    if(root->left == NULL || root->right == NULL)
        return m1 + m2 + 1;
    //3.最后一种情况,也就是左右孩子都不为空,返回最小深度+1即可
        return fmin(m1,m2) + 1; 
} 

代码可以进行简化,当左右孩子为空时 m1m1 和 m2m2 都为 00

可以和情况 22 进行合并,即返回 m1+m2+1m1+m2+1

简化后代码如下:

int minDepth(struct TreeNode *root) {
        if(root == NULL)
            return 0;
        int m1 = minDepth(root->left);
        int m2 = minDepth(root->right);
        //1.如果左孩子和右孩子有为空的情况,直接返回m1+m2+1
        //2.如果都不为空,返回较小深度+1
        return root->left == NULL || root->right == NULL ? m1 + m2 + 1 : fmin(m1,m2) + 1;
} 

思路:

二叉树为空树,最小深度为0;
二叉树不为空树,两子树均不为空,获取左右子树的最小深度,取最小的那个加1;
二叉树不为空树,但两子树其中之一为空,最小深度为子树不为空的最小深度加1。

代码:

#define min(A, B) ((A) < (B) ? (A) : (B))
int minDepth(struct TreeNode* root){
    if (root == NULL) {
        return 0;
    }
    int left = minDepth(root->left);
    int right = minDepth(root->right);

    return (left && right) ? min(left, right) + 1 : left + right + 1;
}

思路:

先判断二叉树是否为空树,然后再逐个判断左右子树是否为空

代码:

#define min(A, B) ((A) < (B) ? (A) : (B))
int minDepth(struct TreeNode* root){
    if (root == NULL) {
        return 0;
    }

    if (root->left == NULL) {
        return minDepth(root->right) + 1;
    } else if (root->right == NULL) {
        return minDepth(root->left) + 1;
    }   

    return min(minDepth(root->left), minDepth(root->right)) + 1;
}

比较好的解释:
四版DFS-一版BFS

好的思路解析

这道题要找出给定二叉树的最小深度,还是DFS来做,其中有一些细节的地方,特殊的测试用例需要注意
在这个递归过程中,我们需要做以下判断递归结束条件:
如果当前节点是NULL,返回0,因为没有节点了不再有深度增加
如果当前节点左右指针都为NULL,说明是叶节点,返回1,深度加一
如果当前左右指针有一个为NULL,那么需要注意,因为为NULL的那一边不算有叶子节点!所以深度只能算不是NULL的那一边
比如测试用例[1,2],根节点1只有左子为2,返回的深度是1+左子节点返回的1=2,而不是1+右子节点返回的0=0。
剩下的是普通继续递归的情况,也就是左子和右子中较小的一方深度+1
根据执行出错的测试用例才能够知道代码漏洞呢,自己还是考虑不够周全!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值