【LeetCode 热题 100】二叉树的最大深度 / 翻转二叉树 / 二叉树的直径 / 验证二叉搜索树

news2025/5/18 7:24:27
头像
⭐️个人主页:@小羊
⭐️所属专栏:LeetCode 热题 100
很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~

动图描述

目录

    • 二叉树的中序遍历
    • 二叉树的最大深度
    • 翻转二叉树
    • 对称二叉树
    • 二叉树的直径
    • 二叉树的层序遍历
    • 将有序数组转换为二叉搜索树
    • 验证二叉搜索树
    • 二叉搜索树中第 K 小的元素
    • 二叉树的右视图
    • 二叉树展开为链表
    • 从前序与中序遍历序列构造二叉树
    • 路径总和
    • 路径总和 II
    • 路径总和 III


二叉树的中序遍历

  • 二叉树的中序遍历

在这里插入图片描述

class Solution {
    vector<int> res;
public:
    vector<int> inorderTraversal(TreeNode* root) {
        dfs(root);
        return res;
    }
    void dfs(TreeNode* root)
    {
        if (root == nullptr) return;
        dfs(root->left);
        res.push_back(root->val);
        dfs(root->right);
    }
};

二叉树的最大深度

  • 二叉树的最大深度

在这里插入图片描述

class Solution {
public:
    int maxDepth(TreeNode* root) {
        if (root == nullptr) return 0;
        int left = maxDepth(root->left);
        int right = maxDepth(root->right);
        return left > right ? left + 1 : right + 1;
    }
};

翻转二叉树

  • 翻转二叉树

在这里插入图片描述

class Solution {
public:
    TreeNode* invertTree(TreeNode* root) {
        if (root == nullptr) return nullptr;
        TreeNode *left = invertTree(root->left);
        TreeNode *right = invertTree(root->right);
        root->left = right;
        root->right = left;
        return root;
    }
};

对称二叉树

  • 对称二叉树

在这里插入图片描述

class Solution {
public:
    bool isSymmetric(TreeNode* root) {
        return dfs(root->left, root->right);
    }
    bool dfs(TreeNode* left, TreeNode* right)
    {
        if (left && right)
        {
            if (left->val != right->val) return false;
            return dfs(left->left, right->right) && dfs(left->right, right->left);
        }
        else if (left != right) return false;
        else return true;
    }
};

二叉树的直径

  • 二叉树的直径

在这里插入图片描述

class Solution {
    int depth;
public:
    int diameterOfBinaryTree(TreeNode* root) {
        dfs(root);
        return depth - 1;
    }
    int dfs(TreeNode* root)
    {
        if (root == nullptr) return 0;
        int left = dfs(root->left);
        int right = dfs(root->right);
        depth = max(depth, left + right + 1);
        return max(left, right) + 1;
    }
};

二叉树的层序遍历

  • 二叉树的层序遍历

在这里插入图片描述

class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        vector<vector<int>> res;
        queue<TreeNode*> q;
        if (root == nullptr) return res;
        q.push(root);
        while (q.size())
        {
            int sz = q.size();
            vector<int> tmp;
            while (sz--)
            {
                TreeNode *node = q.front();
                tmp.push_back(node->val);
                q.pop();
                if (node->left) q.push(node->left);
                if (node->right) q.push(node->right);
            }
            res.push_back(tmp);
        }
        return res;
    }
};

将有序数组转换为二叉搜索树

  • 将有序数组转换为二叉搜索树

在这里插入图片描述

class Solution {
public:
    TreeNode* sortedArrayToBST(vector<int>& nums) {
        return dfs(nums, 0, nums.size() - 1);
    }
    TreeNode* dfs(vector<int>& nums, int l, int r)
    {
        if (l > r) return nullptr;
        int mid = l + (r - l) / 2;
        TreeNode* node = new TreeNode(nums[mid]);
        node->left = dfs(nums, l, mid - 1);
        node->right = dfs(nums, mid + 1, r);
        return node;
    }
};

验证二叉搜索树

  • 验证二叉搜索树

在这里插入图片描述

递归遍历。

class Solution {
public:
    bool isValidBST(TreeNode* root) {
        return dfs(root, LONG_MIN, LONG_MAX);
    }
    bool dfs(TreeNode* root, long min_val, long max_val)
    {
        if (root == nullptr) return true;
        if (root->val <= min_val || root->val >= max_val) return false;
        return dfs(root->left, min_val, root->val) 
            && dfs(root->right, root->val, max_val);
    }
};

前序遍历。

class Solution {
    long prev = LONG_MIN;
public:
    bool isValidBST(TreeNode* root) {
        if (root == nullptr) return true;
        if (isValidBST(root->left) == false) return false;
        if (root->val <= prev) return false;
        prev = root->val; 
        return isValidBST(root->right);
    }
};

二叉搜索树中第 K 小的元素

  • 二叉搜索树中第 K 小的元素

在这里插入图片描述

class Solution {
    int res, cnt;
public:
    int kthSmallest(TreeNode* root, int k) {
        cnt = k;
        dfs(root);
        return res;
    }
    void dfs(TreeNode* root)
    {
        if (root == nullptr) return;
        dfs(root->left);
        if (--cnt == 0) 
        {
            res = root->val;
            return;
        }
        dfs(root->right);
    }
};

二叉树的右视图

  • 二叉树的右视图

在这里插入图片描述

从右往左层序遍历,每次都只拿队头节点的值。

class Solution {
public:
    vector<int> rightSideView(TreeNode* root) {
        vector<int> res;
        if (root == nullptr) return res;
        queue<TreeNode*> q;
        q.push(root);
        while (q.size())
        {
            res.push_back(q.front()->val);
            int sz = q.size();
            while (sz--)
            {
                TreeNode* node = q.front();
                q.pop();
                if (node->right) q.push(node->right);
                if (node->left) q.push(node->left);
            }
        }
        return res;
    }
};

二叉树展开为链表

  • 二叉树展开为链表

在这里插入图片描述

方法一:在前序遍历的过程中把节点存起来,结束后在处理每个节点的指向。

class Solution {
public:
    void flatten(TreeNode* root) {
        vector<TreeNode*> vt;
        dfs(root, vt);
        for (int i = 1; i < vt.size(); i++)
        {
            TreeNode* prev = vt[i - 1], *cur = vt[i];
            prev->left = nullptr;
            prev->right = cur;
        }
    }
    void dfs(TreeNode* root, vector<TreeNode*>& vt)
    {
        if (root)
        {
            vt.push_back(root);
            dfs(root->left, vt);
            dfs(root->right, vt);
        }
    }
};

方法二:寻找前驱结点法。
在前序遍历的过程中,如果当前节点的左子树不为空,则遍历到当前节点的右子树的前一个节点为:当前节点左子树中最右的那个节点。我们在遍历的过程中找到这个前驱结点,将当前节点的右子树拼接到这个前驱节点的右节点上,然后将当前节点的左子树拼接到当前节点的右子树上,最后当前节点左子树置空。

class Solution {
public:
    void flatten(TreeNode* root) {
        TreeNode* cur = root;
        while (cur)
        {
            if (cur->left)
            {
                auto prev = cur->left;
                while (prev->right) prev = prev->right;
                prev->right = cur->right;
                cur->right = cur->left;
                cur->left = nullptr;
            }
            cur = cur->right;
        }
    }
};

从前序与中序遍历序列构造二叉树

  • 从前序与中序遍历序列构造二叉树

在这里插入图片描述

根据前序遍历依次找到根节点,通过找到的根节点找到中序遍历中根节点的位置,从而划分出 [左子树] [根节点] [右子树]。
用哈希表存储中序遍历的值和下标映射关系,以至于能在找到根节点后直接拿到根节点在中序遍历中的位置,然后根据中序遍历的位置递归构建左子树和右子树。

class Solution {
    unordered_map<int, int> index;
public:
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        for (int i = 0; i < inorder.size(); i++)
        {
            index[inorder[i]] = i;
        }
        return dfs(preorder, 0, 0, inorder.size() - 1);
    }
    TreeNode* dfs(vector<int>& preorder, int root, int l, int r)
    {
        if (l > r) return nullptr;
        TreeNode* node = new TreeNode(preorder[root]);
        int id = index[preorder[root]];
        node->left = dfs(preorder, root + 1, l, id - 1);
        node->right = dfs(preorder, root + id - l + 1, id + 1, r);
        return node;
    }
};

路径总和

  • 路径总和

在这里插入图片描述

class Solution {
public:
    bool hasPathSum(TreeNode* root, int targetSum) {
        if (root == nullptr) return false;
        if (root->left == nullptr && root->right == nullptr) 
        {
            return targetSum == root->val;
        }
        return hasPathSum(root->left, targetSum - root->val) 
            || hasPathSum(root->right, targetSum - root->val);
    }
};

路径总和 II

  • 路径总和 II

在这里插入图片描述

class Solution {
    vector<vector<int>> res;
    vector<int> path;
public:
    vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
        dfs(root, targetSum);
        return res;
    }
    void dfs(TreeNode* root, int t)
    {
        if (root == nullptr) return;
        path.push_back(root->val);
        if (root->left == nullptr && root->right == nullptr && t == root->val)
        {
            res.push_back(path);
        }
        dfs(root->left, t - root->val);
        dfs(root->right, t - root->val);
        path.pop_back(); // 回溯
    }
};

路径总和 III

  • 路径总和 III

在这里插入图片描述

class Solution {
    using ll = long long;
    unordered_map<ll, int> pre_cnt; // 记录前缀和及其出现次数
    int t;
public:
    int pathSum(TreeNode* root, int targetSum) {
        t = targetSum;
        pre_cnt[0] = 1; // 前缀和恰好等于目标值
        return dfs(root, 0);
    }
    int dfs(TreeNode* root, ll sum) {
        if (root == nullptr) return 0;
        sum += root->val;
        int count = pre_cnt[sum - t];
        pre_cnt[sum]++;
        count += dfs(root->left, sum);
        count += dfs(root->right, sum);
        pre_cnt[sum]--;
        return count;
    }
};





本篇文章的分享就到这里了,如果您觉得在本文有所收获,还请留下您的三连支持哦~

头像

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

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

相关文章

关于软件测试开发的一些有趣的知识

文章目录 一、什么是测试&#xff1f;二、为什么要软件测试软件测试三、测试的岗位有哪些四 、软件测试和开发的区别五、走测试岗位为什么还要学开发。4、优秀的测试人员具备的素质我为什么走测试岗位 一、什么是测试&#xff1f; 其实这个问题说简单也不简单&#xff0c;说难…

uni-app 开发HarmonyOS的鸿蒙影视项目分享:从实战案例到开源后台

最近&#xff0c;HBuilderX 新版本发布&#xff0c;带来了令人兴奋的消息——uni-app 现在支持 Harmony Next 平台的 App 开发。这对于开发者来说无疑是一个巨大的福音&#xff0c;意味着使用熟悉的 Vue 3 语法和开发框架&#xff0c;就可以为鸿蒙生态贡献自己的力量。 前言 作…

售前工作.工作流程和工具

第一部分 售前解决方案及技术建议书的制作 售前解决方案编写的标准操作步骤SOP: 售前解决方案写作方法_哔哩哔哩_bilibili 第二部分 投标过程关键活动--商务标技术方案 1. 按项目管理--售前销售项目立项 销售活动和销售线索的跟踪流程和工具 1&#xff09;拿到标书&#xff…

GPU与NPU异构计算任务划分算法研究:基于强化学习的Transformer负载均衡实践

点击 “AladdinEdu&#xff0c;同学们用得起的【H卡】算力平台”&#xff0c;H卡级别算力&#xff0c;按量计费&#xff0c;灵活弹性&#xff0c;顶级配置&#xff0c;学生专属优惠。 引言 在边缘计算与AI推理场景中&#xff0c;GPU-NPU异构计算架构已成为突破算力瓶颈的关键技…

【滑动窗口】LeetCode 209题解 | 长度最小的子数组

长度最小的子数组 前言&#xff1a;滑动窗口一、题目链接二、题目三、算法原理解法一&#xff1a;暴力枚举解法二&#xff1a;利用单调性&#xff0c;用滑动窗口解决问题那么怎么用滑动窗口解决问题&#xff1f;分析滑动窗口的时间复杂度 四、编写代码 前言&#xff1a;滑动窗口…

Python绘制南丁格尔玫瑰图:从入门到实战

Python绘制南丁格尔玫瑰图&#xff1a;从入门到实战 引言 南丁格尔玫瑰图&#xff08;Nightingale Rose Chart&#xff09;&#xff0c;也被称为极区图&#xff08;Polar Area Chart&#xff09;&#xff0c;是一种独特的数据可视化方式。这种图表由弗洛伦斯南丁格尔&#xff…

炼丹学习笔记3---ubuntu2004部署运行openpcdet记录

前言 环境 cuda 11.3 python 3.8 ubuntu2004 一、cuda环境检测 ylhy:~/code_ws/OpenPCDet/tools$ nvcc -V nvcc: NVIDIA (R) Cuda compiler driver Copyright (c) 2005-2021 NVIDIA Corporation Built on Sun_Mar_21_19:15:46_PDT_2021 Cuda compilation tools, release 11.3…

深入解析BGP路由反射器与联邦:突破IBGP全连接限制的两种方案

一、引言&#xff1a;大型BGP网络的挑战 在大型BGP网络架构中&#xff0c;传统的IBGP全连接架构会带来严重的扩展性问题。当网络中存在N台路由器时&#xff0c;需要维护N*(N-1)/2个IBGP连接&#xff0c;这对设备资源和运维管理都是巨大挑战。本文将深入解析两种主流解决方案&a…

QT设置MySQL驱动

QSqlDatabase: QMYSQL driver not loaded QSqlDatabase: available drivers: QSQLITE QMYSQL QMYSQL3 QODBC QODBC3 QPSQL QPSQL7 第一步&#xff1a;下载MySQL https://dev.mysql.com/downloads/mysql/ 解压缩下载的安装包&#xff0c;其目录结构如下所示&#xff1a; 第二…

String的一些固定程序函数

append reverse length toString

3.2/Q2,Charls最新文章解读

文章题目&#xff1a;Transition of nighttime sleep duration and sleep quality with incident cardiovascular disease among middle-aged and older adults: results from a national cohort study DOI&#xff1a;10.1186/s13690-025-01577-5 中文标题&#xff1a;中老年人…

大麦(Hordeum vulgare)中 BAHD 超家族酰基转移酶-文献精读129

Systematic identification and expression profiles of the BAHD superfamily acyltransferases in barley (Hordeum vulgare) 系统鉴定与大麦&#xff08;Hordeum vulgare&#xff09;中 BAHD 超家族酰基转移酶的表达谱分析 摘要 BAHD 超家族酰基转移酶在植物中催化和调控次…

docker迅雷自定义端口号、登录用户名密码

在NAS上部署迅雷&#xff0c;确实会带来很大的方便。但是目前很多教程都是讲怎么部署docker迅雷&#xff0c;鲜有将自定义配置的方法。这里讲一下怎么部署&#xff0c;并重点讲一下支持的自定义参数。 一、部署docker 在其他教程中&#xff0c;都是介绍的如下命令&#xff0c…

中国30米年度土地覆盖数据集及其动态变化(1985-2022年)

中文名称 中国30米年度土地覆盖数据集及其动态变化(1985-2022年) 英文名称&#xff1a;The 30 m annual land cover datasets and its dynamics in China from 1985 to 2022 CSTR:11738.11.NCDC.ZENODO.DB3943.2023 DOI 10.5281/zenodo.8176941 数据共享方式&#xff1a…

3D个人简历网站 5.天空、鸟、飞机

1.显示天空 models下新建文件Sky.jsx Sky.jsx // 从 React 库中导入 useRef 钩子&#xff0c;用于创建可变的 ref 对象 import { useRef } from "react"; // 从 react-three/drei 库中导入 useGLTF 钩子&#xff0c;用于加载 GLTF 格式的 3D 模型 import { useGLT…

STM32IIC实战-OLED模板

STM32IIC实战-OLED模板 一&#xff0c;SSD1306 控制芯片1&#xff0c; 主要特性2&#xff0c;I2C 通信协议3&#xff0c; 显示原理4&#xff0c; 控制流程5&#xff0c; 开发思路 二&#xff0c;HAL I2C API 解析I2C 相关 API1&#xff0c;2&#xff0c;3&#xff0c;4&#xf…

c#车检车构客户管理系统软件车辆年审短信提醒软件

# CMS_VehicleInspection 车检车构客户管理系统软件车辆年审短信提醒软件 # 开发背景 软件是给泸州某公司开发的车检车构客户管理系统软件。用于在车检年审到期前一个月给客户发送车检短信提醒 # 功能描述 主要功能&#xff1a;车辆年审前一个月给客户发年审短信提醒&#xf…

通俗版解释CPU、核心、进程、线程、协程的定义及关系

通俗版解释&#xff08;比喻法&#xff09; 1. CPU 和核心 CPU 一个工厂&#xff08;负责干活的总部&#xff09;。核心 工厂里的车间&#xff08;比如工厂有4个车间&#xff0c;就能同时处理4个任务&#xff09;。 2. 进程 进程 一家独立运营的公司&#xff08;比如一家…

大语言模型 11 - 从0开始训练GPT 0.25B参数量 MiniMind2 准备数据与训练模型 DPO直接偏好优化

写在前面 GPT&#xff08;Generative Pre-trained Transformer&#xff09;是目前最广泛应用的大语言模型架构之一&#xff0c;其强大的自然语言理解与生成能力背后&#xff0c;是一个庞大而精细的训练流程。本文将从宏观到微观&#xff0c;系统讲解GPT的训练过程&#xff0c;…

USRP 射频信号 采集 回放 系统

USRP 射频信号采集回放系统 也可以叫做&#xff1a; 利用宽带RF录制和回放系统实现6G技术研究超宽带射频信号采集回放系统使用NI USRP平台实现射频信号录制和回放操作演示USRP也能实现多通道宽带信号流盘回放了&#xff01; 对于最简单的实现方法就是使用LabVIEW进行实现 采…