【Leetcode】代码随想录Day16|二叉树3.0

文章目录

    • 104 二叉树的最大深度
    • 559 n叉树的最大深度
    • 111 二叉树的最小深度
    • 222 完全二叉树的节点个数

104 二叉树的最大深度

  • 递归法:无论是哪一种顺序,标记最大深度
class Solution(object):def depthHelper(self, root, depth):if root:depth += 1left_depth = self.depthHelper(root.left, depth)right_depth = self.depthHelper(root.right, depth)return max(left_depth, right_depth)return depthdef maxDepth(self, root):depth = 0if root:depth = self.depthHelper(root, depth)return depth

优解参考简化:

class Solution(object):def maxDepth(self, root):if not root:return 0ldepth = self.maxDepth(root.left)rdepth = self.maxDepth(root.right)return max(ldepth,rdepth) + 1
  • 迭代法:层序遍历
class Solution:def maxDepth(self, root: TreeNode) -> int:if not root:return 0depth = 0queue = collections.deque([root])while queue:depth += 1for _ in range(len(queue)):node = queue.popleft()if node.left:queue.append(node.left)if node.right:queue.append(node.right)return depth

559 n叉树的最大深度

  • 递归法:需要遍历每个节点的children
"""
# Definition for a Node.
class Node(object):def __init__(self, val=None, children=None):self.val = valself.children = children
"""class Solution(object):def maxDepth(self, root):if not root:return 0childDepth = 0if root.children:childDepth = max([self.maxDepth(child) for child in root.children])return 1 + childDepth

111 二叉树的最小深度

初始思路
与最大深度一样

class Solution(object):def minDepth(self, root):if not root:return 0ldepth = self.minDepth(root.left)rdepth = self.minDepth(root.right)return min(ldepth,rdepth) + 1

问题:
最大深度只要有一个分支有更深的深度,取这个深度就可以了,所有累积到此的分支都是存在的,他们的深度代表了树的深度。但是上述方法中的最小分支却可能是树并不存在的分支,也就不能代表树的深度。如下面这个例子,这个树的深度是3,但是如果用与之前类似的方法,那么在1这个root左子树不存在的时候,就会认为找到了最短的路径深度1。事实上1并不是叶子结点,并不符合对与树深度的定义。所以在找最小路径的时候,要考虑找到的深度究竟能不能算做是整个树的深度。

      1\2/3 

转换思路:
需要判断分支深度为0的情况,如果有且只有一个分支深度为0,那么这个后面的深度是需要算上的,并不能因为其中一个分支深度为0,就在这里截止,当作最小深度的情况。

class Solution(object):def minDepth(self, root):if not root:return 0left = self.minDepth(root.left)right = self.minDepth(root.right)minDepth = 0if left == 0 and right != 0:minDepth = rightelif left != 0 and right == 0:minDepth = leftelse:return 1 + min(left, right)return 1 + minDepth

222 完全二叉树的节点个数

1. 初始思路
递归或迭代遍历所有节点

  • 递归
class Solution(object):def countNodes(self, root):if not root:return 0left = self.countNodes(root.left)right = self.countNodes(root.right)return left + right + 1

Complexity
time: O(n)
space: O(log n),算上了递归系统栈占用的空间

  • 迭代:

Complexity
time: O(n)
space: O(n)

2. 利用完全二叉树的特性

首先我们最想用的肯定是满二叉树,因为直接通过层数就可以算出来节点数量2^h - 1。 但是完全二叉树可能有两种情况:

  • 满二叉树
  • 距离满二叉树只有最后一层按顺序没有填满

为了能够利用简介的满二叉树算法,我们可以通过递归去将输入的树拆解成子满二叉树。对于一个完全二叉树来讲,会有两种拆解方式:
来自代码随想录

来自代码随想录

那么如何判断是否是满二叉树呢?
既然非满二叉树的完全二叉树只有可能是最后一层按照从左往右的顺序右边没有填满,那么只要查看一个树的最后一层的最左边的深度和最后一层的最右边的深度是否一样,就可以判断它是不是满的。

那么总结一下方法:就是往下递归找到最大块的满二叉树组成部分,来计算总共的节点数。

class Solution(object):def getFullHeight(self, root):# return -1 if it is not full# else, return the height of the full binary treeif not root:return 0left = 1right = 1lefttmp = rootrighttmp = rootwhile lefttmp.left:lefttmp = lefttmp.leftleft += 1while righttmp.right:righttmp = righttmp.rightright += 1if left == right:return leftreturn -1 def countNodes(self, root):if not root:return 0h = self.getFullHeight(root)if h == -1:return 1 + self.countNodes(root.left) + self.countNodes(root.right)return 2**h - 1

优解参考简化

  • 优化一:代码量精简
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)  

优化二:将getFullHeight的操作明确只对剩下的一半进行,让另一半以O(1)的复杂度完成,不需要再判断一次满二叉树了。

class Solution:def countNodes(self, root):if not root:return 0leftDepth = self.getDepth(root.left)rightDepth = self.getDepth(root.right)if leftDepth == rightDepth:return pow(2, leftDepth) + self.countNodes(root.right)else:return pow(2, rightDepth) + self.countNodes(root.left)def getDepth(self, root):if not root:return 0return 1 + self.getDepth(root.left)

Complexity
time: O(log n × log n)
space: O(log n)

时间复杂度的解释
H为整个树的高度,n为总节点数。

  1. 判断是否为满二叉树及其深度的时间复杂度为O(H) = O(log n) 【getFullHeight】

  2. 从上面两种由满二叉树构成完全二叉树的方式中可以看出,root.right只有两种可能的高度,H-1或H-2

    • H-1: 少的这个高度就是root那一层,则root.left和root.right相同高度。也就是说,root.left一定是满二叉树,只需要O(1)就可以算出节点数,root.right需要进一步递归判断节点数。
    • H-2:不仅少了root一层的高度,root.left比root.right高一层。也就是说最后一层不满的叶子结点全部都在root.left的范围里面,需要进一步递归判断节点数,而root.right是一个满二叉树,只需要O(1)就可以算出节点数。
  3. 从最后优化版中可以看到,在H层中,递归到每一层的时候,都有一半是满二叉树,可以用O(1) 的方式直接计算出数量,只需要进行一次【getFullHeight】,即对于O(log n)层,每一层进行一次O(log n)的操作,复杂度为 O(log n × log n)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2969023.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

2024华中杯C题光纤传感器平面曲线重建原创论文分享

大家好,从昨天肝到现在,终于完成了2024华中杯数学建模C题的完整论文啦。 给大家看一下目录吧: 目录 摘 要: 10 一、问题重述 12 二.问题分析 13 2.1问题一 13 2.2问题二 14 2.3问题三 14 三、模型假设 15 四、…

基于Java+SpringBoot+Vue前后端分离仓库管理系统

基于JavaSpringBootVue前后端分离仓库管理系统 🍅 作者主页 央顺技术团队 🍅 欢迎点赞 👍 收藏 ⭐留言 📝 🍅 文末获取源码联系方式 📝 🍅 查看下方微信号获取联系方式 承接各种定制系统 &#…

进程控制相关

进程终止 进程终止时,操作系统要释放对应进程申请的相关内核数据结构和对应的代码和数据。其不本质就是释放进程申请的系统资源。 进程终止的常见方式: 1、代码运行完毕且结果正确。 2、代码运行完毕但结果不正确。 3、代码没运行完,进程…

【学习笔记】论文创新点

论文创新点 论文创新点的突破口 论文的烦恼 选择方向,热门方向(但不是最新的)。 经典的、持续时间长的,学习资源多。 应用型创新 适应在交叉学科 数量少 一般需要改进算法 怎么改进是一个很大的问题 因此寻找创新点十分重要 …

《操作系统导论》第26章读书笔记:并发:介绍

《操作系统导论》第26章读书笔记:并发:介绍 —— 杭州 2024-04-18 夜 文章目录 《操作系统导论》第26章读书笔记:并发:介绍0.前言1.实例:线程创建(略)2.为什么更糟糕:共享数据(略)3.核心问题:不…

ruoyi创建子模块

点击项目 -> new -> Module 选择maven模式 构建完成 子项目默认会加入到父项目maven控制在 父项目 pom文件中 dependencyManagement 标签内加入一下代码 新建子模块的名称<!-- 测试--><dependency><groupId>com.safety</groupId><artifact…

记录汇川:五个ST案例

起保停&#xff1a; 简单数学教学&#xff1a; 数据查找&#xff1a; 按钮检测&#xff1a; 数据堆栈&#xff1a;

C#自定义窗体更换皮肤的方法:创建特殊窗体

目录 1.窗体更换皮肤 2.实例 &#xff08;1&#xff09;图片资源管理器Resources.Designer.cs设计 &#xff08;2&#xff09;Form1.Designer.cs设计 &#xff08;3&#xff09;Form1.cs设计 &#xff08;4&#xff09; 生成效果 &#xff08;5&#xff09;一个遗憾 1.窗…

Unity类银河恶魔城学习记录12-17 p139 In game UI源代码

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释&#xff0c;可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili UI.cs using UnityEngine;public class UI : MonoBehaviour {[SerializeFie…

【Linux】创建IDEA桌面快捷方式

Linux系统安装IDEA保姆级教程_linux安装idea-CSDN博客 在Ubuntu上安装Intellij IDEA并创建桌面快捷方式 - 极客子羽 - 博客园 (cnblogs.com) 下载安装包解压到指定目录 /opt/softWare 进入bin目录&#xff0c;ll查看 桌面打开终端&#xff0c;创建文件 touch idea.desktop s…

面试题:Java中int符号数字的位运算与操作 + 原码、反码、补码之间如何进行转换

题目来源 阿里-淘天-技术1面 问题 -1和4做位运算与操作&#xff0c;结果是多少&#xff1f; 答案 正确答案 4 通过Java代码验证如下&#xff1a; 我的回答 -5&#xff0c;但是-5是错误的答案。 面试的时候&#xff0c;面试官没有告诉我对错。 为什么&#xff1f; 到底…

上网行为审计软件有哪些|好用的上网行为管控软件推荐

上述图片中提到的情况&#xff0c;可能有人会有些疑惑&#xff0c;不过无妨。 小编来告诉你是怎么回事&#xff01; 这是因为他们老板使用了上网行为审计软件&#xff01; 一、什么是上网行为审计软件 上网行为审计软件是一种专门用于监控和管理员工或学生上网行为的软件系统…

36. UE5 RPG在激活技能时使用蒙太奇动画

在上一篇文章里面&#xff0c;我们实现了一个简单的火球术&#xff0c;创建了火球术的火球&#xff0c;以及能发射它的技能。很简陋&#xff0c;在技能触发的时候&#xff0c;直接在武器的位置生成火球发射出去。在一篇文章里&#xff0c;我们要实现使用技能时&#xff0c;角色…

盒子模型之怪异盒模型

这个是标准盒模型 这个是怪异盒模型 box-sizing:content-box;默认是标准盒模型 box-sizing:border-box;是怪异盒模型&#xff0c;会挤压里面的内容&#xff0c;不管怎么设置边框始终都是当初设置的200px <!DOCTYPE html> <html lang"en"> <head>…

leetcode199 二叉树的右视图

题目 给定一个二叉树的 根节点 root&#xff0c;想象自己站在它的右侧&#xff0c;按照从顶部到底部的顺序&#xff0c;返回从右侧所能看到的节点值。 示例 输入: [1,2,3,null,5,null,4] 输出: [1,3,4] 解析 这道题首先能想到的办法&#xff0c;就是使用迭代法层次遍历&…

【Linux】文件描述符——万字详解

目录​​​​​​​ 前言 预备知识 复习C语言的文件接口 写方式打开文件 追加方式打开文件 读方式打开文件 系统的文件接口 open close write read 文件描述符 0 & 1 & 2 理解文件描述符 文件描述符的分配规则 重定向的本质 dup2 理解Linux下一切…

近屿OJAC带你解读:AIGC核心知识点LLM

近年来&#xff0c;人工智能&#xff08;AI&#xff09;领域经历了令人瞩目的增长&#xff0c;尤其是自然语言处理&#xff08;NLP&#xff09;。你知道是什么推动了NLP领域的这种飞速发展吗&#xff1f;没错&#xff0c;那就是大型语言模型LLM。这些模型可能会彻底改变我们与科…

【华为 ICT HCIA eNSP 习题汇总】——题目集17

1、以下哪项不属于网络层安全威胁&#xff1f; A、DDos攻击 B、钓鱼攻击 C、IP Spoofing D、IP地址扫描 考点&#xff1a;网络安全 解析&#xff1a;&#xff08;B&#xff09; 钓鱼攻击通常被认为是应用层的安全威胁&#xff0c;也有在网络层进行伪装实施钓鱼攻击&#xff0c;…

揭秘分享京东商品详情数据接口(商品属性,sku,价格)API接口可测试

今天给大家分享关于封装根据京东商品ID或商品链接批量获取京东商品详情数据接口方法&#xff0c;支持高并发请求。 如果你对京东的商品详情数据感兴趣&#xff0c;我建议你采取以下合法和合规的途径&#xff1a; 使用京东开放平台&#xff1a;京东开放平台提供了一系列的API接…

MySQL-使用CPP接入到MySQL

&#x1f4df;作者主页&#xff1a;慢热的陕西人 &#x1f334;专栏链接&#xff1a;MySQL &#x1f4e3;欢迎各位大佬&#x1f44d;点赞&#x1f525;关注&#x1f693;收藏&#xff0c;&#x1f349;留言 本博客主要内容介绍如何在c/cpp代码连接和管理数据库 文章目录 MySQL-…