代码随想录算法训练营第十六天|104.二叉树的最大深度, 559.n叉树的最大深度, 222.完全二叉树的节点个数

一些递归的感悟:

如果在每一次递归好像都有“要查一下”的条件,例如当前点是不是nullptr,当前点作为root是不是perfect tree,这些条件就放到“特殊情况”那里去写。都写完了以后再开始递归过程。

 

 

104.二叉树的最大深度(递归法 - 前序)

力扣

注意:

1. 区分高度和深度。高度是从leaf往上遍历,深度是从root下来。

 2. 1) 求高度用后序遍历,因为【左右中】的逻辑,遍历完左右后,把高度传给parent,然后+1,是求高度的逻辑。

     2) 求深度用前序遍历。

3. 二叉树的深度为根节点最远叶子节点的最长路径上的节点数。

root的高度就是二叉树的最大深度。所以此时按【高度】的求法(后序遍历)也是可行的,从leaf往上求

4. 若为空节点,则高度为0

5. 所以本题实际上是【post-order】,先找出左/右子树谁是maxDepth,然后再+1(中间的一个节点)。是【左右中】的逻辑。

 

559.n叉树的最大深度

力扣

1.思路类似上一题的后序遍历,从下往上遍历,每遍历完一层得到这一层的maxDepth后+1。

2. 终止条件:if(root == nullptr) return 0

3. 具体递归部分为:

for(int i = 0; i < root->children.size(); i++){
    depth = max(depth, maxDepth(root->children[i]);
}

注意一直用depth记录不要每次更新为0了。

4. 最后return 1+depth。

 

111.二叉树的最小深度

力扣

1. 终止条件依然是:if(root == nullptr) return 0;  递归都不要忘了终止条件!

2. 重点是特殊情况:当左子树为nullptr但右子树不是时,此时的最小深度应该是 1+minDepth(右子树),而不是1+min(左,右) = 1。反之同理。具体就是如图所示这个情况:

具体代码为:

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

3. 讨论完特殊情况后,就按maxDepth类似处理即可。

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

 

222.完全二叉树的节点个数 

力扣

perfect tree: 全满的

complete tree: 最后一行集中在左边,其余都是满的

1. 终止条件:也就是“特殊情况”的分类讨论,如果是perfect tree的话可以用公式计算出节点数。

1) 计算perfect tree节点(第一层算1):pow(2, Depth) - 1

2) 如何判断是不是perfect:左子树外侧的深度 == 右子树外侧的深度

注意:为什么只需要判断外侧,因为complete tree最后一行是集中在左侧的,所以一旦出现不perfect,外侧的深度一定会不一样。

因此对于左右子树,都从leftNode = root和rightNode = root开始。然后leftNode只需要一路向左,rightNode一路向右:

//特殊情况
int leftDepth = 0;
int rightDepth = 0;
TreeNode* leftNode = root;
TreeNode* rightNode = root;

while(leftNode){
    leftNode = leftNode->left;
    leftDepth++;
}

while(rightNode){
    rightNode = rightNode->right;
    rightDepth++;
}


if(leftDepth == rightDepth){ //perfect tree
    return pow(2, leftDepth)-1; //此时leftDepth和rightDepth一样所以随便选一个就行
}


//再进行递归部分
return 1 + countNodes(root->left) + countNodes(root->right);
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值