【代码随想录】【算法训练营】【第16天】 [104]二叉树的最大深度 [111]二叉树的最小深度 [222]完全二叉树的节点个数

news2024/11/14 12:10:07

前言

思路及算法思维,指路 代码随想录。
题目来自 LeetCode。

day 16,周四,再坚持一下吧~

题目详情

[104] 二叉树的最大深度

题目描述

104 二叉树的最大深度
104 二叉树的最大深度

解题思路

前提:二叉树的最大深度,等价于二叉树的层数,等价于求最底层二叉树叶子结点的高度。
思路:求二叉树深度:前序遍历;求二叉树高度:后序遍历;求二叉树层数:层级遍历。
重点:二叉树节点的深度:指从根节点到该节点的最长简单路径边的条数或者节点数(取决于深度从0开始还是从1开始);二叉树节点的高度:指从该节点到叶子节点的最长简单路径边的条数或者节点数(取决于高度从0开始还是从1开始)。

代码实现

C语言
层级遍历 队列
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
int maxDepth(struct TreeNode* root) {
    int ans = 0;
    // 判断树非空
    if (root == NULL)
    {
        return ans;
    }
    // 层级遍历, 队列
    struct TreeNode *queue[10000];
    int idx = 0;
    queue[idx++] = root;
    int start = 0;
    while (start < idx)
    {
        int levelCnt = idx - start;
        for (int i = 0; i < levelCnt; i++)
        {
            struct TreeNode *cur = queue[start++];
            if (cur->left)
            {
                queue[idx++] = cur->left;
            }
            if (cur->right)
            {
                queue[idx++] = cur->right;
            }
        }
        ans++;
    }
    return ans;
}
后序遍历 求root的高度,递归
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */

int max(int a, int b)
{
    return (a > b) ? a : b;
}

int hight(struct TreeNode* root)
{
    // 后序遍历求高度,最大深度即为root的高度
    if (root == NULL)
    {
        return 0;
    }
    int leftHight = hight(root->left);
    int rightHight = hight(root->right);
    return 1 + max(leftHight, rightHight);
}

int maxDepth(struct TreeNode* root) {
    // 后序遍历求高度,最大深度即为root的高度,递归
    return hight(root);
}
前序遍历 求root深度,递归
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */

int max(int a, int b)
{
    return (a > b) ? a : b;
}

void depthFun(struct TreeNode* root, int depth, int *result)
{
    // 前序遍历求深度, 注意回溯的过程
    if (root == NULL)
    {
        return ;
    }
    *result = max(*result, depth);
    depthFun(root->left, depth + 1, result);
    depthFun(root->right, depth + 1, result);
    return ;
}

int maxDepth(struct TreeNode* root) {
    // 后序遍历求高度,最大深度即为root的高度,递归
    int result = 0;
    int depth = 0;
    depthFun(root, depth + 1, &result);
    return result;
}

[111] 二叉树的最小深度

题目描述

111 二叉树的最小深度
111 二叉树的最小深度

解题思路

前提:二叉树的最小深度,等价于二叉树最高层叶子结点的层数,等价于求二叉树最高层叶子结点的高度。
思路:求二叉树深度:前序遍历;求二叉树高度:后序遍历;求二叉树层数:层级遍历。
重点:注意叶子结点的含义: (node->left == NULL) && (node->right == NULL)。

代码实现

C语言
层序遍历,队列
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
int minDepth(struct TreeNode* root) {
    int ans = 0;
    // 判断空树
    if (root == NULL)
    {
        return ans;
    }
    // 层序遍历,队列
    struct TreeNode *queue[100000];
    int idx = 0;
    queue[idx++] = root;
    int start = 0;
    while (start < idx)
    {
        int levelCnt = idx - start;
        ans++;
        for (int i = 0; i < levelCnt; i++)
        {
            struct TreeNode *cur = queue[start++];
            // 判断是否为叶子结点
            if ((cur->left == NULL) && (cur->right == NULL))
            {
                // 找到第一个叶子结点,直接退出
                return ans;
            }
            if (cur->left)
            {
                queue[idx++] = cur->left;
            }
            if (cur->right)
            {
                queue[idx++] = cur->right;
            }
        }
    }
    return ans;
}
前序遍历深度,递归
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */

int minFun(int a, int b)
{
    return (a < b) ? a : b;
}

void depthFun(struct TreeNode* root, int depth, int *result)
{
    if (NULL == root)
    {
        return ;
    }
    // 寻找叶子结点
    if ((root->left == NULL) && (root->right == NULL))
    {
        *result = minFun(*result, depth);
        return ;
    }
    depthFun(root->left, depth + 1, result);
    depthFun(root->right, depth + 1, result);
}

int minDepth(struct TreeNode* root) {
    // 判断空树
    if (root == NULL)
    {
        return 0;
    }
    int ans = INT_MAX;
    // 前序遍历,递归
    depthFun(root, 1, &ans);
    
    return ans;
}

[222] 完全二叉树的节点个数

题目描述

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

解题思路

前提:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2^(h-1) 个节点。
思路:普通二叉树遍历;利用完全二叉树特性,拆解为n个满二叉树,利用 2^树深度 - 1 来计算。
重点:完全二叉树的特性。

代码实现

C语言
普通二叉树 先序遍历 递归
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */

void travesal(struct TreeNode *root, int *ans)
{
    if (root == NULL)
    {
        return ;
    }
    //先序遍历
    (*ans)++;
    travesal(root->left, ans);
    travesal(root->right, ans);
}

int countNodes(struct TreeNode* root) {
    int ans = 0;
    travesal(root, &ans);
    return ans;
}
普通二叉树 结点数量 递归
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */

int countNodeNum(struct TreeNode *root)
{
    if (root == NULL)
    {
        return 0;
    }
    int leftNum = countNodeNum(root->left);
    int rightNum = countNodeNum(root->right);
    return (leftNum + rightNum + 1);
}

int countNodes(struct TreeNode* root) {
    int ans = countNodeNum(root);
    return ans;
}
完全二叉树分解成满二叉树,利用满二叉树结点数为2^n -1。
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */

int countNodeNum(struct TreeNode *root)
{
    if (root == NULL)
    {
        return 0;
    }
    int leftDepth = 0;
    int rightDepth = 0;
    struct TreeNode *left = root->left;
    struct TreeNode *right = root->right;
    // 求左侧叶子结点的深度
    while (left)
    {
        leftDepth++;
        left = left->left;
    }
    // 求右侧叶子结点的深度
    while (right)
    {
        rightDepth++;
        right = right->right;
    }
    // 判断是否为满二叉树, 两边深度相同
    // 注意:两侧深度相同的二叉树不是满二叉树,但两侧深度相同的完全二叉树,一定是满二叉树。
    if (leftDepth == rightDepth)
    {
        return (2 << leftDepth) - 1;
    }
    int leftNum = countNodeNum(root->left);
    int rightNum = countNodeNum(root->right);
    return (leftNum + rightNum + 1);
}

int countNodes(struct TreeNode* root) {
    int ans = countNodeNum(root);
    return ans;
}

今日收获

  1. 二叉树的深度、高度;
  2. 完全二叉树的特性。

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

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

相关文章

C#读取.sql文件并执行文件中的sql脚本

有些时候我们需要在程序中编写读取sql脚本文件并执行这些sql语句&#xff0c;但是我们在有些时候会遇到读出来的sql语句不能执行&#xff0c;其实不能执行并不是你的sql脚本文件有错误&#xff0c;而是去执行sql语句的时候&#xff0c;C#代码里面执行sql语句的代码对sql里面的一…

新书推荐:6.2 else if语句

本节必须掌握的知识点&#xff1a; 示例代码二十 代码分析 汇编解析 ■if语句表达形式3 if(表达式1) statement1 else if(表达式2) statement2 else if(表达式3) statement3 …… else statementN 解析&#xff1a; 如果表达式1非0&#xff0c;则执行statement1&#…

基于Netty实现WebSocket服务端

本文基于Netty实现WebSocket服务端&#xff0c;实现和客户端的交互通信&#xff0c;客户端基于JavaScript实现。 在【WebSocket简介-CSDN博客】中&#xff0c;我们知道WebSocket是基于Http协议的升级&#xff0c;而Netty提供了Http和WebSocket Frame的编解码器和Handler&#…

9.3 Go语言入门(变量声明和函数调用)

Go语言入门&#xff08;变量声明和函数调用&#xff09; 目录二、变量声明和函数调用1. 变量声明1.1 使用 var 关键字声明1.2 简短声明1.3 零值1.4 常量 2. 函数调用2.1 函数定义2.2 多个返回值2.3 命名返回值2.4 可变参数2.5 匿名函数和闭包 目录 Go 语言&#xff08;Golang&a…

Windows11下使用Qt5.14.2编译QtXlsx驱动详细步骤

原有&#xff1a;由于系统需要将QTableWidget表格中的数据导出、在Windows下最开始使用Excel.Application组件实现了导出功能&#xff0c;后面将代码转换到Ubuntu20.04下进行编译&#xff0c;发现项目.pro文件中的QT axcontainer和代码.h文件中的#include <QAxObject>跟…

接口自动化基础

1、接口自动化测试 接口自动化&#xff1a;使用工具或代码代替人对接口进行测试的技术。 测试目的&#xff1a;防止开发修改代码时引入新的问题。 l测试时机&#xff1a; 开发进行系统测试转测前&#xff0c;可以先进行接口自动化脚本的编写。 开发进行系统测试转测后&…

dubbo复习:(4) 和springboot 整合时,客户端负载均衡的配置

需要在DubboReference注解指定loadbalance属性。示例如下&#xff1a; package cn.edu.tju.service;import org.apache.dubbo.config.annotation.DubboReference; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Ser…

【全开源】活动报名表单系统(ThinkPHP+Uniapp+uView)

轻松构建高效报名平台 一、引言 随着线上活动的日益增多&#xff0c;一个高效、易用的活动报名表单系统成为了举办各类活动的必备工具。为了满足不同组织和个人的需求&#xff0c;我们推出了功能强大的“活动报名表单系统源码”。本文将为您详细介绍该源码的特点、功能以及使…

燃数科技前端25-40K*14薪一面超简单,下周二面啦

一面 1、自我介绍 2、低代码如何设计的 3、react路由原理 4、react生命周期 5、什么是回调地狱&#xff0c;如何解决 6、jwt和session有什么区别 7、js文件相互引用有什么问题&#xff1f;如何解决 8、一个很大的json文件&#xff0c;前端读取如何优化 面试我的不像是…

实战之快速完成 ChatGLM3-6B 在 GPU-8G的 INT4 量化和本地部署

ChatGLM3 (ChatGLM3-6B) 项目地址 https://github.com/THUDM/ChatGLM3大模型是很吃CPU和显卡的&#xff0c;所以&#xff0c;要不有一个好的CPU&#xff0c;要不有一块好的显卡&#xff0c;显卡尽量13G&#xff0c;内存基本要32GB。 清华大模型分为三种(ChatGLM3-6B-Base&…

部署运行petalinux系统镜像

参考文档《编译 petalinux 系统镜像》编译获取 petalinux 系统镜像&#xff0c;编译生成的各种镜像文件如下&#xff1a; scilogyhunterubuntu1804:~/petalinux/workspace/project0/petalinux$ ls images/linux/ bl31.bin Image pxelinux.cfg rootfs.cpio.gz.u-boot …

【实战JVM】-01-JVM通识-字节码详解-类的声明周期-加载器

【实战JVM】-01-JVM通识-字节码详解-类的声明周期-加载器 1 初识JVM1.1 什么是JVM1.2 JVM的功能1.2.1 即时编译 1.3 常见JVM 2 字节码文件详解2.1 Java虚拟机的组成2.2 字节码文件的组成2.2.1 正确打开字节码文件2.2.2 字节码组成2.2.3 基础信息2.2.3.1 魔数2.2.3.1 主副版本号…

Java 数组的基本使用

目录 含义语法格式语句特点数组的长度数组的元素打印数组显示数组数组的复制扩展示例【12】&#xff1a; 含义 数组&#xff08;array&#xff09;是一种最简单的复合数据类型&#xff0c;它是有序数据的集合&#xff0c;数组中的每个元素具有相同的数据类型&#xff0c;可以用…

一款好用的SSH连接工具-Tabby Terminal 使用教程

简介 Tabby Terminal 是一款现代化的终端应用程序&#xff0c;旨在提供流畅、高效且可定制的用户体验。它具有跨平台兼容性&#xff0c;支持多种操作系统&#xff0c;包括 Windows、macOS 和 Linux。其界面设计简洁美观&#xff0c;允许用户通过插件和主题进行个性化定制。同时…

LeetCode674:最长连续递增序列

题目描述 给定一个未经排序的整数数组&#xff0c;找到最长且 连续递增的子序列&#xff0c;并返回该序列的长度。 连续递增的子序列 可以由两个下标 l 和 r&#xff08;l < r&#xff09;确定&#xff0c;如果对于每个 l < i < r&#xff0c;都有 nums[i] < nums…

selenium 爬取今日头条

由于今日头条网页是动态渲染&#xff0c;再加上各种token再验证&#xff0c;因此直接通过API接口获取数据难度很大&#xff0c;本文使用selenium来实现新闻内容爬取。 selenium核心代码 知识点&#xff1a; 代码中加了很多的异常处理&#xff0c;保证错误后重试&#xff0c;…

抖音:当之无愧的短视频NO.1,新老用户奖励丰厚

论起短视频&#xff0c;如不提行业老大抖音&#xff0c;那是说不过去的。年底抖音也加入了波涛汹涌的红包大战&#xff0c;小伙伴们动动手指就能赚到真金白银的现金&#xff0c;何乐而不为&#xff01; 抖音简介 抖音是北京微播视界科技有限公司于2016年9月20日上线的一款音乐…

系统分析与校正方法——时域法

一、概述 时域法是一种直接在时间域中对系统进行分析和校正的方法。 优点&#xff1a;可以提供系统时间响应的全部信息&#xff0c;直观、准确。缺点&#xff1a;研究系统参数改变引起系统性能指标变化的趋势&#xff0c;及对系统进行校正设计时&#xff0c;时域法不是非常方…

钉钉算是在线办公系统的设计标杆,尽管它依然很难用

不吹不黑&#xff0c;钉钉界面谁的的确简洁&#xff0c;无奈它面向的是场景复杂的办公领域&#xff0c;导致其越来越臃肿难用&#xff0c;反正我是该研究研究&#xff0c;但绝对不会用的。 举报 评论 1

【Axure教程】拖动换位选择器

拖动换位选择器通常用于从一个列表中选择项目并将其移动到另一个列表中。用户可以通过拖动选项来实现选择和移动。这种交互方式在许多Web应用程序中很常见&#xff0c;特别是在需要对项目分组的情况下。 所以今天作者就教大家怎么在Axure用中继器制作一个拖动换位选择器的原型…