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

头像
⭐️个人主页:@小羊
⭐️所属专栏: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.mzph.cn/web/80307.shtml

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

相关文章

Tomcat发布websocket

一、tomcal的lib放入文件 tomcat-websocket.jar websocket-api.jar 二、代码示例 package com.test.ws;import com.test.core.json.Jmode;import javax.websocket.*; import javax.websocket.server.ServerEndpoint; import java.util.concurrent.CopyOnWriteArraySet; imp…

LLM笔记(二)LLM数据基础-分词算法(2)

文章目录 1. 分词算法概述1.1 基于词典的&#xff08;或基于规则的&#xff09;分词算法1.2 基于统计的&#xff08;或基于机器学习的&#xff09;分词算法1.3 基于深度学习的分词算法1.4 子词&#xff08;Subword&#xff09;分词算法1.5 混合分词算法1.6 针对不同语言的特点 …

Uniapp开发鸿蒙应用时如何运行和调试项目

经过前几天的分享&#xff0c;大家应该应该对uniapp开发鸿蒙应用的开发语法有了一定的了解&#xff0c;可以进行一些简单的应用开发&#xff0c;今天分享一下在使用uniapp开发鸿蒙应用时怎么运行到鸿蒙设备&#xff0c;并且在开发中怎么调试程序。 运行 Uniapp项目支持运行到…

数据湖与数据仓库融合:Hudi、Iceberg、Delta Lake 实践对比

在实时与离线一体化的今天,数据湖与数据仓库边界不断融合,越来越多企业选用如 Hudi、Iceberg、Delta Lake 等开源方案实现统一的数据存储、计算、分析平台。本篇将围绕以下关键点,展开实战对比与解决方案分享: ✅ 实时写入能力 ✅ ACID 保证 ✅ 增量数据处理能力 ✅ 流批一…

Python爬虫(29)Python爬虫高阶:动态页面处理与云原生部署全链路实践(Selenium、Scrapy、K8s)

目录 引言&#xff1a;动态爬虫的技术挑战与云原生机遇一、动态页面处理&#xff1a;Selenium与Scrapy的协同作战1.1 Selenium的核心价值与局限1.2 Scrapy-Selenium中间件开发1.3 动态分页处理实战&#xff1a;京东商品爬虫 二、云原生部署&#xff1a;Kubernetes架构设计与优化…

数据结构(十)——排序

一、选择排序 1.简单选择排序 基本思想&#xff1a;假设排序表为[1,…,n]&#xff0c;第i趟排序即从[i,…,n]中选择关键字最小的元素与L[i]交换 eg&#xff1a;给定关键字序列{87&#xff0c;45&#xff0c;78&#xff0c;32&#xff0c;17&#xff0c;65&#xff0c;53&…

小结:jvm 类加载过程

类加载过程 是Java虚拟机&#xff08;JVM&#xff09;将字节码文件&#xff08;.class文件&#xff09;加载到内存中&#xff0c;并转换为运行时数据结构的过程。这个过程可以分为多个步骤&#xff0c;每个步骤都有其特定的任务和目的。根据你提供的信息&#xff0c;以下是类加…

2024 山东省ccpc省赛

目录 I&#xff08;签到&#xff09; 题目简述&#xff1a; 思路&#xff1a; 代码&#xff1a; A&#xff08;二分答案&#xff09; 题目简述&#xff1a; 思路&#xff1a; 代码&#xff1a; K&#xff08;构造&#xff09; 题目&#xff1a; 思路&#xff1a; 代…

turn.js与 PHP 结合使用来实现 PDF 文件的页面切换效果

将 Turn.js 与 PHP 结合使用来实现 PDF 文件的页面切换效果&#xff0c;你需要一个中间步骤将 PDF 转换为 Turn.js 可以处理的格式&#xff08;如 HTML 页面或图片&#xff09;。以下是实现这一功能的步骤和示例代码&#xff1a; 步骤 1: 安装必要的库 首先&#xff0c;你需要…

Python实现NOA星雀优化算法优化卷积神经网络CNN回归模型项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后关注获取。 1.项目背景 在当今数据驱动的时代&#xff0c;卷积神经网络&#xff08;CNN&#xff09;不仅在图像分类任务中…

(面试)View相关知识

1、View绘制流程 onMeasure() 确定View的测量宽高。onLayout() 确定View的最终宽高和四个顶点的位置。onDraw() 将View 绘制到屏幕上。 2、MeasureSpec有三种测量模式&#xff1a; 2.1. EXACTLY&#xff08;精确模式&#xff09; 含义&#xff1a;父容器明确指定了子View的精…

数组名既可作为指针也可作为变量名

在C语言中&#xff0c;数组名在不同的上下文中既可以作为指向数组首个元素的指针&#xff0c;也可以代表整个数组&#xff0c;这是由C语言的设计和语法规则决定的&#xff0c;下面我来详细解释一下。 1. 数组名作为指向首元素的指针 在大多数情况下&#xff0c;当数组名出现在…

Java异常、泛型与集合框架实战:从基础到应用

在Java编程的世界里&#xff0c;异常处理、泛型和集合框架是构建高效、健壮应用的关键技术。通过掌握这些技术&#xff0c;我们可以更好地管理程序运行时的错误&#xff0c;提高代码的复用性和类型安全性。今天&#xff0c;我将通过一系列实验&#xff0c;分享如何在Java中使用…

Spring源码之解决循环依赖 三级缓存

目录 三级缓存核心原理 循环依赖的解决过程 1. Bean A创建过程中提前曝光工厂 2. Bean B创建时发现依赖A&#xff0c;从缓存获取 3. Bean A继续完成初始化 三级缓存的作用总结 二级缓存为何不够解决缓存依赖&#xff1f; 三级缓存如何解决&#xff1f; 为什么不直接在…

K8S Ingress 实现AB测试、蓝绿发布、金丝雀(灰度)发布

假设有如下三个节点的 K8S 集群&#xff1a; ​ k8s31master 是控制节点 k8s31node1、k8s31node2 是工作节点 容器运行时是 containerd 一、场景分析 阅读本文&#xff0c;默认您已经安装了 Ingress Nginx。 1&#xff09;A/B 测试 A/B 测试基于用户请求的元信息将流量路由…

深入理解构造函数,析构函数

目录 1.引言 2.构造函数 1.概念 2.特性 3.析构函数 1.概念 2.特性 1.引言 如果一个类中什么都没有&#xff0c;叫作空类. class A {}; 那么我们这个类中真的是什么都没有吗?其实不是,如果我们类当中上面都不写.编译器会生成6个默认的成员函数。 默认成员函数:用户没有显…

Oracle 11.2.0.4 pre PSU Oct18 设置SSL连接

Oracle 11.2.0.4 pre PSU Oct18 设置SSL连接 1 说明2 客户端配置jdk环境3服务器检查oracle数据库补丁4设置ssla 服务器配置walletb 上传测试脚本和配置文件到客户端c 服务器修改数据库侦听和sqlnet.orad 修改客户端的sqlnet.ora和tnsnames.ora的连接符e 修改java代码的数据连接…

BrepGen中的几何特征组装与文件保存详解 deepwiki occwl OCC包装库

有这种好东西我怎么不知道 AutodeskAILab/occwl: Lightweight Pythonic wrapper around pythonocc 组装几何特征以创建B-rep模型 保存为STEP和STL文件细说 Fast 快速 Searched across samxuxiang/BrepGen Ill explain how BrepGen assembles geometric features to create B-r…

重庆 ICPC 比赛游记

2025.5.9 比赛前一天晚上&#xff0c;激动地睡不着觉&#xff0c;起来收拾了好多东西。&#xff08;其实就四本书&#xff0c;剩下的全是零食……关键在于这四本书基本没用。&#xff09; 2025.5.10 学校丧心病狂的让我们 6:20 到校门口集合坐车&#xff08;据说是怕赶不上比…

0x08.Redis 支持事务吗?如何实现?

回答重点 Redis 支持事务,但它的事务与 MySQL 等关系型数据库的事务有着本质区别。MySQL 中的事务严格遵循 ACID 特性,而 Redis 中的事务主要保证的是命令执行的原子性和隔离性,即所有命令在一个不可分割的操作中顺序执行,不会被其他客户端的命令请求所打断。 最关键的区…