算法打卡Day14

今日任务:

1)104.二叉树的最大深度

2)559.n叉树的最大深度

3)111.二叉树的最小深度

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

104.二叉树的最大深度

题目链接:104. 二叉树的最大深度 - 力扣(LeetCode)

给定一个二叉树 root ,返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。

文章讲解:代码随想录 (programmercarl.com)

视频讲解:二叉树的高度和深度有啥区别?究竟用什么遍历顺序?很多录友搞不懂 | LeetCode:104.二叉树的最大深度哔哩哔哩bilibili

思路:

这道题已经在前一篇文章算法打卡day13层序遍历中做过了,如果采用迭代的方法,就用层序遍历,这题比较简单,遍历完所有节点,每遍历一层深度加一即可

今天采用递归(后序遍历)的方法来做,也可以用前序遍历来做(前序遍历涉及到回溯,我还不理解,等后序二刷再来研究),前序遍历求的就是深度,后序遍历求的是高度

  • 二叉树节点的深度:指从根节点到该节点的最长简单路径边的条数或者节点数(取决于深度从0开始还是从1开始)
  • 二叉树节点的高度:指从该节点到叶子节点的最长简单路径边的条数或者节点数(取决于高度从0开始还是从1开始)

其实弄懂这两个概念,就会发现,在此题求二叉树最大深度中,高度与深度可与转换,当我求二叉树最大深度,也就是最底层叶子节点的深度,也就根节点的高度,所以我们求二叉树最大深度可以转换为,求根节点的高度

求高度我们用后序遍历(左右中),后序遍历是找到叶子节点,然后按左右中每次往上遍历,到时,需要取左数与右树的最大深度

class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right


class Solution:
    # 递归(后序)
    def maxDepth(self, root: [TreeNode]) -> int:
        return self.getHeight(root)

    def getHeight(self,node):
        if not node:
            return 0

        leftDepth = self.getHeight(node.left)  # 左
        rightDepth = self.getHeight(node.right)  # 右

        height = 1 + max(leftDepth, rightDepth)  # 中

        return height

感想:

这题想清楚了就比较简单,最直截了当的就是层序遍历,递归的方法不好想一点,做之前可能要区分高度与深度,但做完就能跳出深度与高度的概念,后序从下网上,就是从下开始计数,前序从上往下遍历,就是从上开始计数

559.n叉树的最大深度

题目链接:559. N 叉树的最大深度 - 力扣(LeetCode)

给定一个 n 叉树,找到其最大深度。 最大深度是指从根节点到最远叶子节点的最长路径上的节点总数。

文章讲解:代码随想录 (programmercarl.com)

思路:

如果采用迭代,层次遍历,这题与上一题一样只是左右节点换成孩子节点了,其他一样

这题如果采用递归的方法,我们也是采用后序遍历

求二叉树深度,我们只需要求出左右树的深度,然后比较,取最大。但是在N叉树中,我们不知道有几个子树,我们需要遍历子树,并用变量记录最大高度,每求一棵树的高度,变与变量比较,将大值重新赋给变量

class Node:
    def __init__(self, val=None, children=None):
        self.val = val
        self.children = children


class Solution:
    def maxDepth(self, root: Node) -> int:
        return self.getHeight(root)

    def getHeight(self,node: Node):
        if not node:
            return 0

        height = 0
        for child in node.children:
            height = max(height,self.getHeight(child))

        return height + 1

111.二叉树的最小深度

题目链接:111. 二叉树的最小深度 - 力扣(LeetCode)

给定一个二叉树,找出其最小深度。 最小深度是从根节点到最近叶子节点的最短路径上的节点数量。 说明: 叶子节点是指没有子节点的节点。 这题在02二叉树的层序遍历中做过,采用的层次遍历

文章讲解:代码随想录 (programmercarl.com)

视频讲解:看起来好像做过,一写就错! | LeetCode:111.二叉树的最小深度哔哩哔哩bilibili

思路:

做了前面几题,这题思路比较好像,递归后序遍历,取左右子树的最小高度即可,但这里面有个坑

最小深度是要找根节点到最近叶子节点的距离,注意是叶子节点,也就就是得遇到左右节点均为空才算遇到了叶子节点

class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right


class Solution:
    def minDepth(self, root: [TreeNode]) -> int:
        return self.getDepth(root)

    def getDepth(self, node):
        # 排除左右节点均为空
        if not node:
            return 0

        leftDepth = self.getDepth(node.left)
        rightDepth = self.getDepth(node.right)

        # 注意,叶子节点是需要左右都为空才为叶子节点
        if node.left == None and node.right:
            depth = rightDepth + 1
        elif node.right == None and node.left:
            depth = leftDepth + 1

        # 现在还剩左右均不为空的情况
        else:
            depth = 1+ min(rightDepth,leftDepth)

        return depth

感想:

以上这两题得递归我写的比较复杂,但是好理解,所以没有放上精简版,如果后面自己熟练了二叉树递归,我在补充上精简版

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

题目链接:222. 完全二叉树的节点个数 - 力扣(LeetCode)

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

示例 1:
输入:root = [1,2,3,4,5,6]
输出:6

示例 2:
输入:root = []
输出:0


示例 3:

输入:root = [1]
输出:1
提示:
树中节点的数目范围是[0, 5 * 10^4]
0 <= Node.val <= 5 * 10^4
题目数据保证输入的树是 完全二叉树

文章讲解:代码随想录 (programmercarl.com)

视频讲解:要理解普通二叉树和完全二叉树的区别! | LeetCode:222.完全二叉树节点的数量哔哩哔哩bilibili

二叉树求节点个数统一思路:

这题有两个思路,不管什么二叉树求节点个数,我们可以用迭代层序遍历,或者递归后序遍历,遍历完计数即可,这样会把每个节点遍历一遍

  • 时间复杂度:O(n)
  • 空间复杂度:O(log n)
lass TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

class Solution:
    # 一般二叉树求解方法
    def countNodes(self, root: [TreeNode]) -> int:
        return self.getNum(root)

    def getNum(self,node):
        if not node:
            return 0
        leftNum = self.getNum(node.left)
        rightNum = self.getNum(node.right)

        totalNode = leftNum + rightNum + 1

        return totalNode

完全二叉树求节点个数思路

对于完全二叉树,我们的遍历过程可以简化,不用遍历所有节点,我们只需要找出二叉树中的满二叉树,满二叉树知道其深度k,可以利用公式2^k-1得到节点个数

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

        

  • 满二叉树:如果一棵二叉树只有度为0的结点和度为2的结点,并且度为0的结点在同一层上,则这棵二叉树为满二叉树。

        

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

如果是满二叉树,直接求节点,如果不是,则需要分别递归左孩子,和右孩子,递归到某一深度一定会有左孩子或者右孩子为满二叉树,然后依然可以按照情况1来计算。

那么如何判断某个树是不是满二叉树

我们只需要判断树的左右最外层是否相等

如,这一种就不等

继续往下找

左边已经找到,计算节点即可,右边继续

class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

class Solution:
    # 一般二叉树求解方法
    def countNodes(self, root: [TreeNode]) -> int:
        return self.getNum(root)

    def getNum(self,node):
        if not node:
            return 0

        left = node.left
        leftDepth = 1

        right = node.right
        rightDepth = 1

        # 求左子树深度
        while left:
            left = left.left
            leftDepth += 1
        # 求右子树深度
        while right:
            right = right.right
            rightDepth += 1

        if leftDepth == rightDepth:
            return 2**leftDepth - 1

        return self.getNum(node.left) + self.getNum(node.right) + 1

感想:

这题需要自己多画画图,搞清楚完全二叉树概念,下次碰到,不能想到,就用最直接的二叉树统一方法,能够做出来是第一步,优化是第二步

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

视频讲解|基于非对称纳什谈判的多微网电能共享运行优化策略

1 主要内容 该讲解视频对应的程序链接为基于非对称纳什谈判的多微网电能共享运行优化策略_吴锦领&#xff0c;主要内容是对《基于非对称纳什谈判的多微网电能共享运行优化策略》的matlab复现&#xff0c;解决的是微网间基于非对称纳什谈判的P2P电能交易共享问题&#xff0c;基…

js生成笛卡尔集合

let arr[[黑, 金, 白],[16G, 32G],[电信, 移动, 联通], ]let listarr.reduce((a, b) > { return a.flatMap(x > b.map(y > [...x, y]))}, [[]] )console.log(list)生成结果

20240322,结构类型,枚举,

一&#xff0c;枚举 1.1 常量符号化 程序中用符号表达数字&#xff0c;增加程序的可读性&#xff1f; #include<stdio.h>//能跑&#xff0c;但是报错不推荐将字符串转为CHAR** const int red0; const int yellow1; const int green2; //为撒在前面&#xff1f; int…

移动硬盘加Type-C接口充电:革新存储与充电体验

随着科技的飞速发展&#xff0c;电子设备的功能和性能也在不断提升。近年来&#xff0c;移动硬盘作为数据存储的重要工具&#xff0c;其接口和充电方式的革新也备受关注。特别是Type-C接口的普及&#xff0c;为移动硬盘带来了前所未有的便利。本文将深入探讨移动硬盘加入Type-C…

Linux 源码安装: PostgreSQL 15.6数据库

Linux 源码安装&#xff1a; PostgreSQL 15.6数据库 1、下载 postgresql-15.6.tar.gz 源码包2、安装postgresql-15.62.1、解压 tar.gz 文件2.2、进入解压后的目录2.3、创建 "postgres" 用户和对应的用户组2.4、创建data目录&#xff0c;授权2.5、编译 PostgreSQL2.6、…

【Qt】使用Qt实现Web服务器(五):QtWebApp上传文件、详解请求数据处理过程

1、示例 1)演示 2)上传图片 3)显示图片 2、源码 示例源码Demo1->FileUploadController void FileUploadController::service(HttpRequest& request, HttpResponse& response)

Linux docker7--私有镜像仓库registry和UI搭建及使用

一、对于开源的镜像&#xff0c;如redis&#xff0c;nginx等&#xff0c;可以通过官方仓库Docker Hub&#xff0c;或者国内的阿里云等共有仓库下载获取到镜像。但是企业内对于自己的研发产品不可能往公共仓库去发布镜像的&#xff0c;一般都会搭建私有的镜像仓库&#xff0c;保…

快速排序(递归)

快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法&#xff0c;其基本思想为&#xff1a;任取待排序元素序列中的某元素作为基准值&#xff0c;按照该排序码将待排序集合分割成两子序列&#xff0c;左子序列中所有元素均小于基准值&#xff0c;右子序列中所有元素均大…

哲♂学家带你深♂入了♂解结构体及结构体内存大小问题

目录 概要 一、结构体的声明 二、结构体变量的创建和初始化 三、结构体的特殊声明 四、结构体内存对齐 1、对齐原则 2、例一 对齐数 计算方法 3、例二 总结 概要 结构体是我们日常编程中经常要用到的一种自定义类型&#xff0c;使用起来也是十分的方便。接下来就由…

Git常用操作命令

Git常用操作命令 前言 Git是一个分布式版本控制系统&#xff0c;用于跟踪和管理软件开发项目的版本历史。Git 是我们日常工作中使用频率极高的工具&#xff0c;各种指令让人眼花缭乱&#xff0c;这里对Git的一些相关命令进行总结。 常用命令 一般来说&#xff0c;日常使用g…

今日AI:Gemini Pro1.5向所有人开放;Stable Diffusion核心团队集体离职;HeyGen5.0上线视频翻译功能;剪映内测视频翻译功能

欢迎来到【今日AI】栏目!这里是你每天探索人工智能世界的指南&#xff0c;每天我们为你呈现AI领域的热点内容&#xff0c;聚焦开发者&#xff0c;助你洞悉技术趋势、了解创新AI产品应用。 新鲜AI产品点击了解&#xff1a;AIbase - 智能匹配最适合您的AI产品和网站 &#x1f91…

十七、LockSupport

TestLockSupport 淘宝面试题&#xff1a;实现一个容器,提供两个方法,add,size。写两个线程,线程1添加10个元素到容器中,线程2实现监控元素的个数,当个数到5个时,线程2给出提示并结束面试题:写一个固定容量同步容器,拥有put和get方法,以及 getcount方法,能够支持2个生产者线程以…

企业数字化转型:是竞争力的关键,还是行业炒作?

企业作为市场经济活动的核心主体&#xff0c;其角色已经从传统的资源集聚和生产组织形式逐步演变为数据驱动、智能决策的创新引擎。数字化转型对于企业而言&#xff0c;并非炒作概念&#xff0c;而是实实在在提升竞争力的关键路径。 什么是企业&#xff1f; 企业是市场经济体系…

网络安全是什么? 为什么要学网络安全 ?网络安全怎么学习?

网络安全是什么&#xff1f; 网络安全是指保护计算机网络、网络设备、应用程序、数据和用户免受非法访问、攻击、破坏或泄漏的过程和技术。网络安全包括多个领域&#xff0c;例如网络防御、漏洞管理、加密技术、身份验证和访问控制等等。 网络安全非常重要&#xff0c;因为现…

【C++】string类模拟实现

个人主页 &#xff1a; zxctscl 如有转载请先通知 文章目录 1. 前言2. 构造函数和析构函数3. 遍历3.1 下标[]3.2 迭代器 4. Modifiers4.1 push_back和append4.2 4.3 insert4.4 erase4.5 swap 5.Capacity5.1 resize5.2 clear 6. 深浅拷贝6.1 浅拷贝&#xff08;值拷贝&#xff0…

【MySQL】基本查询(1)

【MySQL】基本查询&#xff08;1&#xff09; 目录 【MySQL】基本查询&#xff08;1&#xff09;表的增删改查Create单行数据 全列插入多行数据 指定列插入插入否则更新替换 RetrieveSELECT 列全列查询指定列查询查询字段为表达式为查询结果指定别名结果去重 WHERE 条件英语不…

【MySQL】3.2MySQL事务和存储引擎

MySQL事务 一、MySQL事物的概念 事务是一种机制&#xff0c;包含了一件事的完整的一个过程 ●事务是一种机制、一个操作序列&#xff0c;包含了一组数据库操作命令&#xff0c;并且把所有的命令作为一个整体一起向系统提交或撤销操作请求&#xff0c;即这一组数据库命令要么…

关于java字节码文件加载过程中,各种变量和常量的存储位置

java变量存储位置 前提 下面的东西都是在jdk1.8基础上做出的探究 首先我们先解释一下在各种网站上出现的一些名词到底是什么&#xff1f; 1.字面量&#xff1a;声明为final的int、long、double、char等基本类型的常量值&#xff08;如final int a 1 这是一个常量值&#x…

宝塔面板系列——两种方式安装青龙面板

因为最近旧windows服务器到期了&#xff0c;在搬服务器&#xff0c;新服务器尝试用Linux系统。过程中有很多不懂的地方&#xff0c;只能边搬迁边学边弄&#xff0c;顺带记录下来&#xff0c;哪天又要搬迁了&#xff0c;翻翻自己的文章也就一应俱全了。 非科班出身&#xff0c;选…

yarn安装包时报错error Error: certificate has expired

安装教程&#xff1a; 配置镜像地址&#xff1a; npm config set registry https://registry.npmmirror.com//镜像&#xff1a;https://developer.aliyun.com/mirror/NPM 安装yarn&#xff1a; npm install --global yarn查看版本&#xff1a; yarn --version卸载&#xff…