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

101 阅读5分钟

104. 二叉树的最大深度

题目

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

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

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

思路

之前用层序遍历做过一次,有印象,层序遍历很简单

代码

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {number}
 */
var maxDepth = function(root) {
    const queue = []
    let count =0
    root&&queue.push(root)
    while (queue.length) {
        let size = queue.length
        while (size--) {
            let node = queue.shift()
            node.left&&queue.push(node.left)
            node.right&&queue.push(node.right)
        }
        count++
    }
    return count
};

优化:

用递归做,三部曲:

  1. 确定传入的参数,根节点
  2. 确定返回值,返回深度
  3. 确定逻辑,分别对左右子树求深度,然后里面最大的一个加上当前树的深度1,递归实现

代码

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {number}
 */
var maxDepth = function(root) {
    if (!root) return 0
    let leftDepth = maxDepth(root.left)
    let rightDepth = maxDepth(root.right)
    let depth = 1 + Math.max(leftDepth,rightDepth)
    return depth
};

总结:

不难

559. N 叉树的最大深度

题目

给定一个 N 叉树,找到其最大深度。

最大深度是指从根节点到最远叶子节点的最长路径上的节点总数。

N 叉树输入按层序遍历序列化表示,每组子节点由空值分隔(请参见示例)。

思路

利用层序遍历,很简单 自己也写了一版递归,但是用自己写的方法卡住了,去查了gpt告诉我必须添加一个对子节点数量判断的条件才通过,不知道为什么

代码

/**
 * // Definition for a Node.
 * function Node(val,children) {
 *    this.val = val;
 *    this.children = children;
 * };
 */

/**
 * @param {Node|null} root
 * @return {number}
 */

// 层序迭代
var maxDepth = function(root) {
    const queue = []
    let count =0
    root&&queue.push(root)
    while (queue.length) {
        let size = queue.length
        while (size--) {
            let node = queue.shift()
            for (let i = 0;i<node.children.length;i++){
                node.children[i]&&queue.push(node.children[i])
            }
        }
        count++
    }
    return count
};

// 自己写的递归

var maxDepth = function(root) {
    if (!root) return 0
    if (root.children.length === 0) return 1 // 必须要加这个条件才能通过
    const arr = []
    for (let i =0;i<root.children.length;i++) {
        if (root.children[i]) {
            let iDepth = maxDepth(root.children[i])
            arr.push(iDepth)
        }
    }
    let depth = 1+Math.max(...arr)
    return depth
};

优化:

看了一下代码随想录的递归写法,很简洁

代码

var maxDepth = function(root) {
    if (!root) return 0
    let depth = 0
    for (let i =0;i<root.children.length;i++) {
        depth = Math.max(depth,maxDepth(root.children[i]))
    }
    return depth + 1
};

总结:

这道题本身不难,很多知识点用的都是之前学过的,递归的问题后来问了代码随想录群友解决了,因为如果不对子树长度判断,那么arr数组为空,此时求最大值就会一直返回infinity

111. 二叉树的最小深度

题目

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

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

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

思路

之前用层序遍历写过一次,今天用递归自己写了一遍,如果一个节点的左右节点都为空,就直接返回当前深度,初始为1,然后对左右节点的深度进行递归获取,选择最小的那一个累加 注意:如果某节点不存在,对其处理的话,可能还是会返回深度,所以添加了一个判断条件,如果这个节点不存在,最后深度取值就是infinity无限

代码

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {number}
 */

// 层序遍历
var minDepth = function(root) {
    const queue = []
    let count =0
    root&&queue.push(root)
    while (queue.length) {
        let size = queue.length
        count++
        while (size--) {
            let node = queue.shift()
            if (!node.left&&!node.right) {
                return count
            }
            node.left&&queue.push(node.left)
            node.right&&queue.push(node.right)
        }
    }
    return count
};

// 自己写的递归
var minDepth = function(root) {
    if (!root) return 0
    let depth = 1
    if (!root.left&&!root.right) return depth
    // console.log(minDepth(root.right||Infinity))
    depth = Math.min(minDepth(root.left)||Infinity,minDepth(root.right)||Infinity)
    return depth+1
};

优化:

看了一下代码随想录的递归,也考虑到了某节点不存在的情况,处理方式是额外增加两个判断条件

代码

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

总结:

不是很难,自己也能写出来,感觉之前的学习对这几次写题的帮助很大

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

题目

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

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

思路

递归:

  1. 设置参数和返回值,参数是当前的节点,返回当前节点左节点数量+右节点数量+1
  2. 设置返回条件,如果当前节点为null,返回0
  3. 设置单层逻辑,分别对左右节点取节点数量,最后返回节点数量和+1 迭代:层序遍历

代码

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {number}
 */

// 递归
var countNodes = function(root) {
    if (!root) return 0
    let leftNum = countNodes(root.left)
    let rightNum = countNodes(root.right)
    return leftNum+rightNum+1
};

// 迭代
var countNodes = function(root) {
    const que = []
    let count = 0
    root&&que.push(root)
    while (que.length) {
        let size = que.length
        while (size--) {
            let node = que.shift()
            count++
            node.left&&que.push(node.left)
            node.right&&que.push(node.right)
        }
    }
    return count
};

总结:

感觉不难,独立完成

Day16总结

二叉树从开始写到现在的很多题,逻辑都很相似,把基础打牢,对各种题型都能理解