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

本文主要是介绍代码随想录算法训练营第16天 |● 104.二叉树的最大深度 559.n叉树的最大深度 ● 111.二叉树的最小深度 ● 222.完全二叉树的节点个数,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 前言
  • 104.二叉树的最大深度
    • 思路
      • 知识点
    • 方法一 递归法
    • 方法二 迭代法
  • 559. n叉树的最大深度
  • 111.二叉树的最小深度
    • 思路
    • 方法一 后向遍历递归法
    • 方法二 迭代法
  • 222.完全二叉树的节点个数
    • 思路
    • 方法一 当成普通二叉树来做
    • 方法二 利用完全二叉树的特性
  • 总结


前言

所有的题目一刷都是优先掌握递归,迭代法没看,记不住。打十个做完之后再说吧
104和111没有看先序遍历的代码

104.二叉树的最大深度

在这里插入图片描述

思路

知识点

记住深度和高度的定义:1. 从1开始 计数 2. 深度和高度与我们主观常识一致
在这里插入图片描述

总体思路:求解最大深度就是求解根节点的高度;💛

因为求深度是前序遍历,求高度是后序遍历【在子节点的高度上加1就是根节点的高度】,后序遍历要比前序遍历在本题中简洁一些,所以本题使用后序遍历的求高度;
💟具体实现细节:单层递归中求解的逻辑是,当前节点的高度为子节点高度+1;【递归法的第三步】
递归三部曲
在这里插入图片描述
先序遍历有c++代码,非常直观的从上往下的递归。也可以看

方法一 递归法

class Solution(object):def maxDepth(self, root):""":type root: TreeNode:rtype: int"""def getheight(root):if not root: return 0height_left = getheight(root.left)height_right =getheight(root.right)height = 1+max(height_left,height_right)return heightreturn getheight(root)
###精简版
class Solution(object):def maxDepth(self, root):""":type root: TreeNode:rtype: int"""if not root: return 0return 1 + max(self.maxDepth(root.left), self.maxDepth(root.right))

方法二 迭代法

559. n叉树的最大深度

这题目我也刷了

class Solution:def maxDepth(self, root: 'Node') -> int:if not root:return 0max_depth = 1for child in root.children:max_depth = max(max_depth, self.maxDepth(child) + 1)return max_depth

111.二叉树的最小深度

在这里插入图片描述

思路

总体思路:与上面的最大深度差不多,但是不能单纯将max改成min。

  • 如果直接max改成min的话,例如下面的最右边的节点6会被算成高度为1,因为min子节点的结果为0,也就是将6当成叶子了;或者按照老师讲解的,根节点中会算左边的null为0.,这样最小深度就是1了。
    下面是老师的讲解
    在这里插入图片描述

  • 所以这条题目相较于104的改动就是加上分类讨论:(这是递归法的第三步单层逻辑)

    • 子节点中,一个是null,一个有节点,按照有节点的那个算
    • 两个都有的话选择min的那个
    • 两个都是空那就是0【可以与上面那个合并】
      在这里插入图片描述

方法一 后向遍历递归法

自己写的错误

  1. 在类里面调用递归的时候,记得加上self
  2. 下面是教程里面的代码,我写的时候is None用not来代替了,我觉着这样国家好一些
class Solution:def getDepth(self, node):if node is None:return 0leftDepth = self.getDepth(node.left)  # 左rightDepth = self.getDepth(node.right)  # 右# 当一个左子树为空,右不为空,这时并不是最低点if node.left is None and node.right is not None:return 1 + rightDepth# 当一个右子树为空,左不为空,这时并不是最低点if node.left is not None and node.right is None:return 1 + leftDepthresult = 1 + min(leftDepth, rightDepth)return resultdef minDepth(self, root):return self.getDepth(root)### 精简代码
class Solution:def minDepth(self, root):if root is None:return 0if root.left is None and root.right is not None:return 1 + self.minDepth(root.right)if root.left is not None and root.right is None:return 1 + self.minDepth(root.left)return 1 + min(self.minDepth(root.left), self.minDepth(root.right))

方法二 迭代法

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

在这里插入图片描述

思路

方法一 当成普通二叉树来做

注意:使用后序遍历的代码是最简洁的
先序遍历:参考104题目教程里面的先序遍历写法,明显会复杂一些,为啥呢,因为需要一个全局变量来++1
单层处理逻辑:后序遍历到这个节点时,已经遍历的节点个数为它的子节点个数之和+1
递归三步走:
在这里插入图片描述

每一个都需遍历一下,时间复杂度为O(n)

class Solution(object):def countNodes(self, root):""":type root: TreeNode:rtype: int"""if not root: return 0cright = self.countNodes(root.right)cleft = self.countNodes(root.left)return 1+cright+cleft

方法二 利用完全二叉树的特性

首先回顾完全二叉树定义:
在这里插入图片描述
总体思路:利用满二叉树如果知道深度为n,节点个数就是2**n-1的特性,避免遍历所有的节点;
递归第三步单层处理逻辑

  • 完全二叉树只有两种情况,情况一:就是满二叉树,情况二:最后一层叶子节点没有满。
    • 对于情况一,可以直接用 2^树深度 - 1 来计算,注意这里根节点深度为1。

    • 对于情况二,左右孩子节点数之和加1

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

      在这里插入图片描述
      如何判断是否为完全二叉树:最左边一层和最右边一层节点数相同,这样就只需要遍历最外侧的就行
      在这里插入图片描述
      注意事项

  1. left和right侧边count的起始为1
  2. 2的阶数写为(2 << leftDepth) - 1 #注意(2<<1) 相当于2^2,所以leftDepth初始为0
class Solution(object):def countNodes(self, root):""":type root: TreeNode:rtype: int"""# if not root: return 0# cright = self.countNodes(root.right)# cleft = self.countNodes(root.left)# return 1+cright+cleftif not root: return 0#判断是否为满二叉树left = root.leftright = root.rightleft_height, right_height = 1,1# 注意这个是1while(left):left_height +=1left = left.leftwhile(right):right_height += 1right = right.rightif right_height == left_height:return 2**right_height -1cleft = self.countNodes(root.left)cright = self.countNodes(root.right)return 1+cleft+cright#还有一种技巧计算2的阶数,这时起始height要计算为0;代码如下,
class Solution:def countNodes(self, root: TreeNode) -> int:if not root:return 0left = root.leftright = root.rightleftDepth = 0 #这里初始为0是有目的的,为了下面求指数方便rightDepth = 0while left: #求左子树深度left = left.leftleftDepth += 1while right: #求右子树深度right = right.rightrightDepth += 1if leftDepth == rightDepth:return (2 << leftDepth) - 1 #注意(2<<1) 相当于2^2,所以leftDepth初始为0return self.countNodes(root.left) + self.countNodes(root.right) + 1

更加简洁的写法:完全二叉树写法2【教程里面的】
两侧同时顺着边数,直到有一条边为none,然后依据是否同时到底来判断是否为满二叉树;

class Solution: # 利用完全二叉树特性def countNodes(self, root: TreeNode) -> int:if not root: return 0count = 1left = root.left; right = root.rightwhile left and right:count+=1left = left.left; right = right.rightif not left and not right: # 如果同时到底说明是满二叉树,反之则不是return 2**count-1return 1+self.countNodes(root.left)+self.countNodes(root.right) 

总结

比较有意思,今天都不想听申论课了。还是算法好玩。。。。可惜找不到工作

这篇关于代码随想录算法训练营第16天 |● 104.二叉树的最大深度 559.n叉树的最大深度 ● 111.二叉树的最小深度 ● 222.完全二叉树的节点个数的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1000080

相关文章

C#实现千万数据秒级导入的代码

《C#实现千万数据秒级导入的代码》在实际开发中excel导入很常见,现代社会中很容易遇到大数据处理业务,所以本文我就给大家分享一下千万数据秒级导入怎么实现,文中有详细的代码示例供大家参考,需要的朋友可... 目录前言一、数据存储二、处理逻辑优化前代码处理逻辑优化后的代码总结前言在实际开发中excel导入很

SpringBoot+RustFS 实现文件切片极速上传的实例代码

《SpringBoot+RustFS实现文件切片极速上传的实例代码》本文介绍利用SpringBoot和RustFS构建高性能文件切片上传系统,实现大文件秒传、断点续传和分片上传等功能,具有一定的参考... 目录一、为什么选择 RustFS + SpringBoot?二、环境准备与部署2.1 安装 RustF

Python实现Excel批量样式修改器(附完整代码)

《Python实现Excel批量样式修改器(附完整代码)》这篇文章主要为大家详细介绍了如何使用Python实现一个Excel批量样式修改器,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一... 目录前言功能特性核心功能界面特性系统要求安装说明使用指南基本操作流程高级功能技术实现核心技术栈关键函

Python实现精确小数计算的完全指南

《Python实现精确小数计算的完全指南》在金融计算、科学实验和工程领域,浮点数精度问题一直是开发者面临的重大挑战,本文将深入解析Python精确小数计算技术体系,感兴趣的小伙伴可以了解一下... 目录引言:小数精度问题的核心挑战一、浮点数精度问题分析1.1 浮点数精度陷阱1.2 浮点数误差来源二、基础解决

深度解析Python中递归下降解析器的原理与实现

《深度解析Python中递归下降解析器的原理与实现》在编译器设计、配置文件处理和数据转换领域,递归下降解析器是最常用且最直观的解析技术,本文将详细介绍递归下降解析器的原理与实现,感兴趣的小伙伴可以跟随... 目录引言:解析器的核心价值一、递归下降解析器基础1.1 核心概念解析1.2 基本架构二、简单算术表达

从入门到精通详解Python虚拟环境完全指南

《从入门到精通详解Python虚拟环境完全指南》Python虚拟环境是一个独立的Python运行环境,它允许你为不同的项目创建隔离的Python环境,下面小编就来和大家详细介绍一下吧... 目录什么是python虚拟环境一、使用venv创建和管理虚拟环境1.1 创建虚拟环境1.2 激活虚拟环境1.3 验证虚

深度解析Java @Serial 注解及常见错误案例

《深度解析Java@Serial注解及常见错误案例》Java14引入@Serial注解,用于编译时校验序列化成员,替代传统方式解决运行时错误,适用于Serializable类的方法/字段,需注意签... 目录Java @Serial 注解深度解析1. 注解本质2. 核心作用(1) 主要用途(2) 适用位置3

Java MCP 的鉴权深度解析

《JavaMCP的鉴权深度解析》文章介绍JavaMCP鉴权的实现方式,指出客户端可通过queryString、header或env传递鉴权信息,服务器端支持工具单独鉴权、过滤器集中鉴权及启动时鉴权... 目录一、MCP Client 侧(负责传递,比较简单)(1)常见的 mcpServers json 配置

从基础到高级详解Python数值格式化输出的完全指南

《从基础到高级详解Python数值格式化输出的完全指南》在数据分析、金融计算和科学报告领域,数值格式化是提升可读性和专业性的关键技术,本文将深入解析Python中数值格式化输出的相关方法,感兴趣的小伙... 目录引言:数值格式化的核心价值一、基础格式化方法1.1 三种核心格式化方式对比1.2 基础格式化示例

Redis实现高效内存管理的示例代码

《Redis实现高效内存管理的示例代码》Redis内存管理是其核心功能之一,为了高效地利用内存,Redis采用了多种技术和策略,如优化的数据结构、内存分配策略、内存回收、数据压缩等,下面就来详细的介绍... 目录1. 内存分配策略jemalloc 的使用2. 数据压缩和编码ziplist示例代码3. 优化的