打卡第15天------二叉树

最近公司给我派活儿太多了,要干好多活儿,好多工作任务要处理,我都没时间刷题了。leetcode上的题目通过数量一直停留在原地不动,我真的很着急呀,我现在每天过的都有一种紧迫感,很着急,有一种与时间赛跑的感觉,真的时间过的太快了,没有任何人能够阻挡住时间的年轮向前推进的脚步,时间真的过的太快了。

一、平衡二叉树

leetcode题目链接:110.平衡二叉树

题目描述:

给定一个二叉树,判断它是否是 平衡二叉树 。

一棵高度平衡二叉树定义为:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。

强调一波概念:

  • 二叉树节点的深度:从根节点到该节点的最长简单路径的条数;
  • 二叉树节点的高度:从该节点到根节点的最长简单路径的条数;

一句话总结:深度指「从上到下」,高度指「从下到上」下图更加直观:

在高度与深度的计算中:leetcode上是以节点为1度,但维基百科是边为1度,暂时以leetcode为准。

求高度适合后序遍历,求深度适合前序遍历,可以看一下我写的JS代码,在leetcode上提交可以通过:

/**
 * 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 {boolean}
 */
// 采用后序遍历的方式,左、右、根来解决此问题,迭代法
var isBalanced = function(root) {

  const depth = (root) => {
    if (root == null) {
      return 0;
    }

    const leftHeight = depth(root.left)
    // 返回-1,表示不是该节点不是平衡二叉树,那么整个树就不是平衡二叉树了
    if (leftHeight == -1) {
      return -1;
    }
    const rightHeight = depth(root.right)
    if (rightHeight == -1) {
      return -1;
    }

    let result;
    if (Math.abs(leftHeight - rightHeight) > 1) {
      result = -1;
    } else {
      result = 1 + Math.max(leftHeight, rightHeight);
    }

    return result
  }

  return !(depth(root) === -1)
};
二、二叉树的所有路径

leetcode题目链接:257. 二叉树的所有路径

题目描述:

给定一个二叉树,返回所有从根节点到叶子节点的路径。

解题思路:

这道题目要求从根节点到叶子的路径,所以需要前序遍历,这样才方便让父节点指向孩子节点,找到对应的路径。

看一下JS代码吧:

/**
 * 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 {string[]}
 */
// 采用递归法,前序遍历方式:根、左、右
var binaryTreePaths = function(root) {

  const result = [];
  // 1.确定递归函数
  const fn = (node, currPath) => {
    // 2、确定终止条件
    if (node.left == null && node.right == null) {
      currPath += node.val;
      result.push(currPath)
      return
    }
    // 3、确定单层逻辑
    currPath += `${node.val}->`;
    node.left && fn(node.left, currPath)
    node.right && fn(node.right, currPath)
  }

  fn(root, '')
  return result;
};
三、左叶子之和

leetcode题目链接:404.左叶子之和

题目描述:

计算给定二叉树的所有左叶子之和。

采用后序遍历,递归遍历。

判断当前节点是不是左叶子是无法判断的,必须通过节点的父节点来判断其左孩子是不是左叶子。

如果该节点的左节点不为空,该节点的左节点的左节点为空,该节点的左节点的右节点为空,则找到了一个左节点,判断代码如下:

if (node->left != NULL && node->left->left == NULL && node->left->right == NULL) {
    左叶子节点处理逻辑
    node->left就是一个左叶子
}

具体看一下JS实现代码:

/**
 * 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 sumOfLeftLeaves = function(root) {

  const nodeSum = (node) => {
    if (node == null) return 0;

    if (node.left == null && node.right == null) return 0;

    let leftNums = sumOfLeftLeaves(node.left)
    let rightNums = sumOfLeftLeaves(node.right)

    let midValue = 0;
    if (node.left != null && node.left.left == null && node.left.right == null) {
      midValue = node.left.val;
    }
    let sum = midValue + leftNums + rightNums;
    return sum;
  }
  return nodeSum(root);
};
四、完全二叉树的节点个数

leetcode题目链接:222.完全二叉树的节点个数

题目描述:

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

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

完全二叉树只有两种情况:情况一:就是满二叉树,情况二:最后一层叶子节点没有满。

对于情况一,直接用公式计算:2^树深度 - 1 来计算,注意这里根节点深度为1;

对于情况二,分别递归左孩子和右孩子,递归到某一深度,一定会有左孩子或者右孩子为满二叉树,然后采用情况一来计算。

来看一下JS代码吧:

/**
 * 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}
 */
// 使用完全二叉树,后续遍历的方式统计节点数量,左、右、根
// 小知识:当一个节点都满的情况下,有一个计算公式来计算节点数量:2^k - 1,k表示节点的高度
var countNodes = function(root) {
  if (root == null) return 0;

  let left = root.left;
  let right = root.right;
  // 左侧节点的高度
  let leftHeight = 0;
  // 右侧节点的高度
  let rightHeight = 0;

  while (left) {
    left = left.left;
    leftHeight++;
  }
  while (right) {
    right = right.right;
    rightHeight++;
  }
  if (leftHeight === rightHeight) {
    return Math.pow(2, leftHeight + 1) - 1;
  }

  const leftNums = countNodes(root.left)
  const rightNums = countNodes(root.right)

  const result = leftNums + rightNums + 1;
  return result;
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值