代码随想录算法训练营第十四天|leetcode104、111、222题

一、leetcode第104题

本题要求二叉树的最大深度,可以用迭代和递归两种方法进行,迭代法我选用的是层序遍历的方法,底层逻辑与前几天的层序遍历代码类似,只是加入记录深度的cnt变量,每次在队列里将该层所有元素弹出时便将cnt加一,这样最后求得的即为最大深度;递归法相对比较简洁,只需要加入递归终止条件(根结点为空)并且返回左右子树的最大深度加一即可。

具体代码如下:

递归法:

class Solution {
public:
    int maxDepth(TreeNode* root) {
    if(root==NULL)
    {
        return 0;
    }
    return max(maxDepth(root->left)+1,maxDepth(root->right)+1);
    }
};

迭代法:

class Solution {
public:
    int maxDepth(TreeNode* root) {
    if(root==NULL)
    {
        return 0;
    }
    queue<TreeNode*>qu;
    qu.push(root);
    int cnt=0;
    while(!qu.empty())
    {
        int size=qu.size();
        for(int i=0;i<size;i++)
        {
            TreeNode*a=qu.front();
            qu.pop();
            if(a->left){qu.push(a->left);}
            if(a->right){qu.push(a->right);}
        }
        cnt++;
    }
    return cnt;
    }
};

二、leetcode第111题

本题要求二叉树的最小深度,该题与求最大深度有些不同,最小深度是要求到叶子结点的最小深度,如果一个结点有左子树没有右子树则高度为右子树最大高度+1而不是1,因此限制条件比求最大深度要多,同样是利用递归但本题要将结点是否有左右子树的条件分开来写才能符合题意。

具体代码如下:

class Solution {
public:
    int minDepth(TreeNode* root) {
    if(root==NULL)
    {
        return 0;
    }
    else if(root->right==NULL&&root->left!=NULL)
    {
        return minDepth(root->left)+1;
    }
    else if(root->right!=NULL&&root->left==NULL)
    {
        return minDepth(root->right)+1;
    }
    else
    {
        return min(minDepth(root->left),minDepth(root->right))+1;
    }
    }
};

三、leetcode第222题

本题要求完全二叉树的结点个数,如果当做普通二叉树来求结点个数可以通过前序、中序、后序、层序遍历来解决,时间复杂度为O(n),如果要剪短程序运行时间则需要利用完全二叉树和满二叉树的特性,将完全二叉树分成数个满二叉树来计算,而满二叉树的结点个数为2的h次方-1,所以重点在于如何分成数个满二叉树,这里利用完全二叉树的特性,用两个指针一个遍历左下结点,一个遍历右下结点,如果高度相同则为满二叉树,最后利用递归求得左右子树的结点个数,加一即为完全二叉树的结点个数。这个方法时间复杂度仍为O(n),但是遍历结点的个数较少,前面的方法需要遍历所有结点,该方法只需要遍历外侧结点而不需要遍历内侧结点,当二叉树深度较深时,时间减少的会较为明显。

具体代码如下:

class Solution {
public:
    int countNodes(TreeNode* root) {
    if(root==NULL)
    {
        return 0;
    }
    TreeNode*lchild=root->left;
    TreeNode*rchild=root->right;
    int ldepth=0;
    int rdepth=0;
    while(lchild)
    {
        lchild=lchild->left;
        ldepth++;
    }
    while(rchild)
    {
        rchild=rchild->right;
        rdepth++;
    }
    if(ldepth==rdepth)
    {
        return (2<<ldepth)-1;
    }
    int leftnum=countNodes(root->left);
    int rightnum=countNodes(root->right);
    return leftnum+rightnum+1;
    }
};

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值