104.二叉树的最大深度

题目链接:

https://leetcode.cn/problems/maximum-depth-of-binary-tree/

题目描述:

给定一个二叉树,找出其最大深度。

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

说明: 叶子节点是指没有子节点的节点。

思路:

这个问题很容易通过递归解决,一颗树的最大深度=右左子树最大深度的最大值+1。

代码:

var maxDepth = function(root) {
    if(!root) return 0
    return Math.max(maxDepth(root.left), maxDepth(root.right))+1
};

111.二叉树的最小深度

题目链接:

https://leetcode.cn/problems/minimum-depth-of-binary-tree/

题目描述:

给定一个二叉树,找出其最小深度。

最小深度是从根节点到最近叶子节点的最短路径上的节点数量。

说明:叶子节点是指没有子节点的节点。

思路:

类比上一题,同样使用递归。一颗树的最小深度=左右子树最小深度的最小值+1 ?这里有坑,题目描述的最小深度的终点必须要是叶子节点。如果一个根节点的左子树为空的,右子树的最小深度为5,按照上面的

公式,这颗树的最小深度为 0+1=1,但实际上是5+1=6。

所以一颗树的最小深度应该分类讨论:

  1. 左子树为空,这棵树的最小深度=右子树最小深度+1
  2. 右子树为空,这棵树的最小深度=左子树最小深度+1
  3. 否则,这颗树的最小深度=左右子树最小深度的最小值+1

代码:

var minDepth = function(root) {
    if(!root) return 0
    let leftDepth = minDepth(root.left)
    let rightDepth = minDepth(root.right)
    if(leftDepth === 0){
        return rightDepth + 1
    }
    else if(rightDepth === 0){
        return leftDepth + 1
    }
    else{
        return Math.min(leftDepth, rightDepth) + 1
    }
};

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

题目链接:

https://leetcode.cn/problems/count-complete-tree-nodes/

题目描述:

给你一棵 完全二叉树 的根节点 root ,求出该树的节点个数。

完全二叉树 的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2h 个节点。

思路:

使用各种方式将二叉树完全遍历一边自然可以得到节点个数。但是没有利用到题目中完全二叉树的性质。

对这题来说,完全二叉树的两个性质十分重要:

  1. 完全二叉树的特殊类型为满二叉树。k层的满二叉树,节点数为\(2^k-1\)
  2. 完全二叉树最后一层的节点是从左到右连续排列的

先补充判断完全二叉树是否是满二叉树的方法:使用两个指针分别从不断左子树和右子树向下移动,如果两个指针同时到达叶子节点说明这棵树为满二叉树。

利用递归解决这题,树的节点个数=左子树的节点个数+右子树的节点个数+1。对每个子树:首先判断其是不是满二叉树,如果是满二叉树,直接利用公式求出节点个数;如果不是满二叉树,就继续递归。那么的递归的终止条件就是以当前节点为根节点的树是否是满二叉树,如果是直接返回节点数。

代码:

var countNodes = function(root) {
    if(!root) return 0
    let leftCur = root.left
    let rightCur = root.right
    let depth = 1
    while(leftCur && rightCur){
        leftCur = leftCur.left
        rightCur = rightCur.right
        depth++
    }
    if(!(leftCur || rightCur)) return 2**depth - 1

    return countNodes(root.left) + countNodes(root.right) + 1
};