当前位置: 首页 > news >正文

Day15--二叉树--222. 完全二叉树的节点个数,110. 平衡二叉树,257. 二叉树的所有路径,404. 左叶子之和

Day15–二叉树–222. 完全二叉树的节点个数,110. 平衡二叉树,257. 二叉树的所有路径,404. 左叶子之和

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

思路参考自:完全二叉树的节点数,你真的会算吗?

参考二:《代码随想录》:

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

对于情况一,可以直接用 2^树深度 - 1 来计算,注意这里根节点深度为1。

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

这里关键在于如何去判断一个左子树或者右子树是不是满二叉树呢?

在完全二叉树中,如果递归向左遍历的深度等于递归向右遍历的深度,那说明就是满二叉树。

思路:完全二叉树,它的左右子树,其中至少有一颗是满二叉树。满二叉树直接根据公式计算,另一颗按照普通二叉树计算。

//  完全二叉树,它的左右子树,其中至少有一颗是满二叉树。
//  满二叉树直接根据公式计算,另一颗按照普通二叉树计算。
//  对于“不是满二叉树”的那颗子树,往下遍历的时候,也可能会有“满二叉树”的情况
//  本代码优化的速度就在于,凡是“满二叉树”就套公式。
class Solution {public int countNodes(TreeNode root) {// 其实这种就一句话的函数,是可以直接写在调用方法里的。// 多写一个方法是因为,这里的节点叫root,容易误解。叫node容易理解。return getNodeNum(root);}private int getNodeNum(TreeNode node) {// 基本上所有代码就是为了“判断是否是满二叉树”if(node==null){return 0;}// 分左右子树TreeNode left = node.left;TreeNode right = node.right;// 记录左右子树的高度// 初始化为1是因为,判断左右子树是否高度相等,是在cur本节点判断的// 如果成立,证明从本节点开始就是满二叉树,要加上本层int leftHeight = 1;int rightHeight = 1;// 统计高度while (left != null) {left = left.left;leftHeight++;}while (right != null) {right = right.right;rightHeight++;}// 如果左右子树高度相同,是一颗满二叉树,可以直接根据公式计算if (leftHeight == rightHeight) {return (int) Math.pow(2, leftHeight) - 1;}// 如果不是满二叉树,则按照普通二叉树的逻辑计算return countNodes(node.left) + countNodes(node.right) + 1;}
}

思路:

递归法:完全当成普通二叉树来算

class Solution {public int countNodes(TreeNode root) {return getNodesNum(root);}private int getNodesNum(TreeNode node) {// 节点为空,返回0if (node == null) {return 0;}// 递归左子树int leftNum = getNodesNum(node.left);// 递归右子树int rightNum = getNodesNum(node.right);// 子树节点+1(自身)->返回给上一层int curNum = leftNum + rightNum + 1;return curNum;}
}

110. 平衡二叉树

思路:

  • 后序遍历法:自底向上统计
  • 如果高度差大于1,返回-1做标记给上层
  • 每一层算高度的时候:取左右子树之中的max,然后+1,当做是本层的高度(因为高度是自底向上算的)
//  后序遍历法:自底向上统计
class Solution {public boolean isBalanced(TreeNode root) {return getHeight(root) == -1 ? false : true;}private int getHeight(TreeNode node) {if (node == null) {return 0;}int leftHeight = getHeight(node.left);int rightHeight = getHeight(node.right);// 如果下层返回的有-1,直接返回-1给上层if (leftHeight == -1 || rightHeight == -1) {return -1;}// 如果高度差大于1,返回-1做标记给上层if (Math.abs(leftHeight - rightHeight) > 1) {return -1;}// 取左右子树之中的max,然后+1,当做是本层的高度(因为高度是自底向上算的)return Math.max(leftHeight, rightHeight) + 1;}
}

257. 二叉树的所有路径

思路:后序遍历:自下而上传递字符串,把孩子传上的字符串拼接本层,加工后传给上一层

// 后序遍历:自下而上传递字符串,把孩子传上的字符串拼接本层,加工后传给上一层
class Solution {public List<String> binaryTreePaths(TreeNode root) {return getChildrenString(root);}private List<String> getChildrenString(TreeNode node) {List<String> list = new ArrayList<>();if (node == null) {return list;}// 拼接左节点传上来的字符串if (node.left != null) {List<String> leftList = getChildrenString(node.left);// 每一个字符串,都要加上本节点的val和"->"// 然后重新加到本节点的list里,每一个node都会新一个listfor (String s : leftList) {String temp = node.val + "->" + s;list.add(temp);}}// 拼接右节点传上来的字符串if (node.right != null) {List<String> rightList = getChildrenString(node.right);for (String s : rightList) {String temp = node.val + "->" + s;list.add(temp);}}// 如果是叶子节点,直接返回本节点的val的字符串形式if (node.left == null && node.right == null) {list.add("" + node.val);}return list;}
}

404. 左叶子之和

思路:

递归遍历。要保证node.left是个叶子,才要它的值。

class Solution {public int sumOfLeftLeaves(TreeNode root) {return getLeftSum(root);}private int getLeftSum(TreeNode node) {int leftNodeSum = 0;int rightNodeSum = 0;if (node.right != null) {rightNodeSum = getLeftSum(node.right);}if (node.left != null) {leftNodeSum = getLeftSum(node.left);// 要保证node.left是个叶子,才要它的值if (node.left.left == null && node.left.right == null) {return leftNodeSum + rightNodeSum + node.left.val;}}return leftNodeSum + rightNodeSum;}
}
http://www.dtcms.com/a/308297.html

相关文章:

  • 企业级部署 (基于tomcat与nginx)
  • 新书速览|R语言数据分析从入门到实践
  • Linux大页内存导致服务内存不足
  • Docker部署的PostgreSQL慢查询日志配置指南
  • 当文档包含图文混排表格时,如何结合大模型(如DeepSeek-VL)和OCR提取数据
  • 468. 验证IP地址
  • Ps2025
  • Python字典完全指南:从基础到实战(2025版)
  • 03 基于sklearn的机械学习-线性回归、损失函数及其推导
  • 大数据之Hive
  • MPU6050模块
  • 排序算法-选择排序(选择排序、堆排序)(动图演示)
  • 数据库Day04
  • 探索 Vue 3.6 新特性:Vapor Mode 与高性能 Web 应用开发
  • 【计算机网络】IP地址、子网掩码、网关、DNS、IPV6是什么含义?计算机中如何设置子网掩码与网关?
  • 大数据精准获客平台的破局之道:数据大集网的深度赋能
  • JavaEE初阶1.0
  • 【Unity】实现小地图
  • QT信号和槽怎么传输自己定义的数据结构
  • Redis哨兵模式搭建
  • 【普中STM32精灵开发攻略】--第 2 章 开发板功能及使用介绍
  • Qt C++实现KD树
  • BH1750模块
  • 上证50期权2400是什么意思?
  • 常见中间件漏洞
  • 腾讯云edge
  • 【SpringMVC】拦截器,实现小型登录验证
  • 对于前端工程化的理解
  • 仓库管理系统-9-前端之Main主要区域的新增表单
  • 用AI一键生成可交互知识图谱:Knowledge Graph Generator 让信息可视化触手可及