当前位置: 首页 > news >正文

letcode 分类练习 树的遍历

letcode 分类练习 树的遍历

  • 树的构建
  • 递归遍历
    • 前序遍历
    • 中序遍历
    • 后序遍历
  • 迭代遍历
    • 前序遍历
    • 中序遍历
    • 后序遍历
  • 层序遍历
    • 层序遍历可以解决的问题
      • 107. 二叉树的层序遍历 II
      • 199. 二叉树的右视图
      • 637. 二叉树的层平均值
      • 429. N 叉树的层序遍历
      • 515.在每个树行中找最大值
      • 116.填充每个节点的下一个右侧节点指针
      • 117.填充每个节点的下一个右侧节点指针II
      • 104.二叉树的最大深度
      • 111.二叉树的最小深度

树的构建

输入数组:[8, 3, 10, 1, 6, null, 14, null, null, 4, 7, 13]

#include <iostream>
#include <vector>
#include <queue>
#include <memory>using namespace std;// 定义二叉树节点结构
struct TreeNode {int val;TreeNode* left;TreeNode* right;TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};// 根据向量数组构建二叉树
TreeNode* constructBinaryTree(const vector<int*>& nums) {if (nums.empty() || !nums[0]) {return nullptr;}// 使用队列进行层序遍历构建树queue<TreeNode*> q;TreeNode* root = new TreeNode(*nums[0]);q.push(root);int i = 1;while (!q.empty() && i < nums.size()) {TreeNode* current = q.front();q.pop();// 构建左子节点if (i < nums.size() && nums[i]) {current->left = new TreeNode(*nums[i]);q.push(current->left);}i++;// 构建右子节点if (i < nums.size() && nums[i]) {current->right = new TreeNode(*nums[i]);q.push(current->right);}i++;}return root;
}

递归遍历

前序遍历

class Solution {
public:vector<int> result;void dfs(TreeNode* root){if(!root) return;result.push_back(root->val);if(root -> left)dfs(root -> left);if(root -> right)dfs(root-> right);}vector<int> preorderTraversal(TreeNode* root) {dfs(root);return result;}
};

中序遍历

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

后序遍历

class Solution {
public:vector<int> result;void dfs(TreeNode* root){if(!root) return;if(root->left)dfs(root->left);if(root->right)dfs(root->right);result.push_back(root -> val);}vector<int> postorderTraversal(TreeNode* root) {dfs(root);return result;}
};

迭代遍历

前序遍历

class Solution {
public:vector<int> preorderTraversal(TreeNode* root) {stack<TreeNode*> s;vector<int> result;if(!root)return result;while(root || !s.empty()){while(root){s.push(root);// 这里while一直向左就开始收集result.push_back(root->val);root = root -> left;}TreeNode* node = s.top();s.pop();root = node -> right;}return result;}
};

中序遍历

在这里插入图片描述

class Solution {
public:vector<int> inorderTraversal(TreeNode* root) {stack<TreeNode*> s;vector<int> result;if(!root)return result;while(root || !s.empty()){while(root){s.push(root);root = root -> left;}TreeNode* node = s.top();s.pop();// 弹栈的时候才收集result.push_back(node->val);root = node -> right;}return result;}
};

后序遍历


后序遍历的迭代方式有区别,就是弹栈后,不是收集,而是判断它的右孩子节点,如果右孩子为空,说明它是叶子节点,这个时候我们收集到result里,并且把这个标记成前驱节点,root再置为空。如果右孩子不为空,我们要像访问左孩子这样继续遍历。

class Solution {
public:vector<int> postorderTraversal(TreeNode* root) {stack<TreeNode*> s;vector<int> result;if(!root) return result;TreeNode* prev;while(root || !s.empty()){while(root){s.push(root);root = root -> left;}TreeNode* root = s.top();s.pop();if(root -> right == nullptr && root != prev){result.push_back(root -> val);prev = root;root = root -> right;}else{s.push(root);root = root -> right;}}return result;}
};

层序遍历

class Solution {
public:vector<vector<int>> levelOrder(TreeNode* root) {queue<TreeNode*>q;vector<vector<int>> result;if(!root)return result;q.push(root);while(!q.empty()){int k = q.size();vector<int> tmp;for(int i =0;i<k;i++){TreeNode* node = q.front();q.pop();tmp.push_back(node -> val);if(node->left)q.push(node->left);if(node->right)q.push(node->right);}result.push_back(tmp);}return result;}
};

层序遍历可以解决的问题

107. 二叉树的层序遍历 II

class Solution {
public:vector<vector<int>> levelOrderBottom(TreeNode* root) {queue<TreeNode*>q;vector<vector<int>> result;if(!root)return result;q.push(root);while(!q.empty()){int k = q.size();vector<int> tmp;for(int i =0;i<k;i++){TreeNode* node = q.front();q.pop();tmp.push_back(node -> val);if(node->left)q.push(node->left);if(node->right)q.push(node->right);}result.push_back(tmp);}reverse(result.begin(), result.end());return result;}
};

199. 二叉树的右视图

class Solution {
public:vector<int> rightSideView(TreeNode* root) {queue<TreeNode*>q;vector<int> result;if(!root)return result;q.push(root);while(!q.empty()){int k = q.size();vector<int> tmp;for(int i =0;i<k;i++){TreeNode* node = q.front();q.pop();if(i==k-1) result.push_back(node -> val);if(node->left)q.push(node->left);if(node->right)q.push(node->right);}}return result;}
};

637. 二叉树的层平均值

在这里插入图片描述

class Solution {
public:vector<double> averageOfLevels(TreeNode* root) {queue<TreeNode*>q;vector<double> result;if(!root)return result;q.push(root);while(!q.empty()){int k = q.size();vector<int> tmp;double sum = 0;for(int i =0;i<k;i++){TreeNode* node = q.front();sum += node->val;q.pop();if(i==k-1) result.push_back(sum/k);if(node->left)q.push(node->left);if(node->right)q.push(node->right);}}return result;}
};

429. N 叉树的层序遍历

class Solution {
public:vector<vector<int>> levelOrder(Node* root) {queue<Node*> q;vector<vector<int>>result;if(!root)return result;q.push(root);while(!q.empty()){int k = q.size();vector<int>tmp;for(int i =0;i<k;i++){Node* node = q.front();q.pop();tmp.push_back(node->val);for(auto c : node->children){q.push(c);}}result.push_back(tmp);}return result;}
};

515.在每个树行中找最大值

class Solution {
public:vector<int> largestValues(TreeNode* root) {queue<TreeNode*> q;vector<int> result;if(!root) return result;q.push(root);while(!q.empty()){int k = q.size();int maxV = INT_MIN;for(int i =0;i<k;i++){TreeNode* node = q.front();q.pop();if(node -> val > maxV)maxV = node -> val;if(i == k-1)result.push_back(maxV);if(node -> left)q.push(node -> left);if(node -> right)q.push(node -> right);}}return result;}
};

116.填充每个节点的下一个右侧节点指针

在这里插入图片描述

class Solution {
public:Node* connect(Node* root) {queue<Node*> q;if(!root) return root;q.push(root);while(!q.empty()){int k = q.size();Node* tmp = NULL;for(int i =0;i<k;i++){Node* node = q.front();q.pop();if(tmp != NULL)tmp -> next = node;tmp = node;if(node -> left)q.push(node -> left);if(node -> right)q.push(node -> right);}}return root;}
};

117.填充每个节点的下一个右侧节点指针II

class Solution {
public:Node* connect(Node* root) {queue<Node*> q;if(!root) return root;q.push(root);while(!q.empty()){int k = q.size();Node* tmp = NULL;for(int i =0;i<k;i++){Node* node = q.front();q.pop();if(tmp != NULL)tmp -> next = node;tmp = node;if(node -> left)q.push(node -> left);if(node -> right)q.push(node -> right);}}return root;}
};

104.二叉树的最大深度

在这里插入图片描述

class Solution {
public:int maxDepth(TreeNode* root) {queue<TreeNode*> q;if(!root) return 0;q.push(root);int count = 0;while(!q.empty()){int k = q.size();count++;for(int i =0;i<k;i++){TreeNode* node = q.front();q.pop();if(node -> left)q.push(node -> left);if(node -> right)q.push(node -> right);}}return count;}
};

111.二叉树的最小深度

如果是叶子节点提前返回

class Solution {
public:int minDepth(TreeNode* root) {queue<TreeNode*> q;if(!root) return 0;q.push(root);int count = 0;while(!q.empty()){int k = q.size();count++;for(int i =0;i<k;i++){TreeNode* node = q.front();q.pop();if(!node -> left && !node -> right)return count;if(node -> left)q.push(node -> left);if(node -> right)q.push(node -> right);}}return count;}
};

相关文章:

letcode 分类练习 树的遍历

letcode 分类练习 树的遍历 树的构建递归遍历前序遍历中序遍历后序遍历 迭代遍历前序遍历中序遍历后序遍历 层序遍历层序遍历可以解决的问题107. 二叉树的层序遍历 II199. 二叉树的右视图637. 二叉树的层平均值429. N 叉树的层序遍历515.在每个树行中找最大值116.填充每个节点的…...

redisssion分布式锁

分布式锁的问题 基于setnx的分布式锁实现起来并不复杂&#xff0c;不过却存在一些问题。 锁误删问题 第一个问题就是锁误删问题&#xff0c;目前释放锁的操作是基于DEL&#xff0c;但是在极端情况下会出现问题。 例如&#xff0c;有线程1获取锁成功&#xff0c;并且执行完任…...

嘎嘎嘎拿到去年想要的包

一年多了 继续&#xff0c;把项目收尾吧 好好学前端&#xff0c;外企&#xff01;react&#xff01;从0开始&#xff0c;紧迫&#xff01;加油&#xff01;...

前奏编曲:如何编写二段式前奏

选好音源 Pianoteq 6 STAGE比较明亮些&#xff0c;适合做前奏的音源 确定和弦进行 比如4536251&#xff0c;每个小节2和弦&#xff0c;每个小节的和弦弹一下 优化和弦进行衔接和织体 二段式不用对和弦进行就近解决的处理&#xff0c;因为前奏前后要形成对比。 前半部分往…...

征服云端:Kubernetes如何让微服务与云原生技术如虎添翼

引言 在这个数字化转型的时代&#xff0c;微服务架构已经成为构建现代应用程序的首选方式。它不仅提高了开发效率&#xff0c;还增强了系统的可扩展性和灵活性。而随着云计算技术的迅猛发展&#xff0c;云原生的概念逐渐深入人心&#xff0c;它代表了一种全新的软件开发方法论…...

开源AI智能名片系统与高级机器学习技术的融合应用:重塑商务交流的未来

摘要&#xff1a;在数字化浪潮的推动下&#xff0c;人工智能&#xff08;AI&#xff09;技术&#xff0c;尤其是机器学习领域的快速发展&#xff0c;正深刻改变着各行各业的面貌。开源AI智能名片系统作为这一变革的先锋&#xff0c;通过集成并优化多种高级机器学习技术&#xf…...

Java中synchronized的偏向锁是如何减少锁开销的

偏向锁&#xff08;Biased Locking&#xff09;是一种优化 Java synchronized 锁的机制&#xff0c;旨在减少在无竞争情况下的锁开销。它通过将锁偏向于单个线程来优化锁的性能。以下是偏向锁减少锁开销的具体方式和原理&#xff1a; 偏向锁的工作原理 锁的初始状态: 当一个对…...

react18 + ts 使用video.js 直播.m3u8格式的视频流

一、安装依赖 我使用的video.js版本是8.17.3&#xff0c;从 Video.js 7.x 开始&#xff0c;HLS 支持被内置到了 Video.js 中所以不需要安装其他依赖 npm i video.js 二、创建VideoPlayer组件 import React, { useEffect, useRef } from react import videojs from video.js …...

使用 onBeforeRouteLeave 组合式函数提升应用的用户体验

title: 使用 onBeforeRouteLeave 组合式函数提升应用的用户体验 date: 2024/8/14 updated: 2024/8/14 author: cmdragon excerpt: 摘要&#xff1a;本文介绍了在Nuxtjs中使用onBeforeRouteLeave组合式函数来提升应用用户体验的方法。onBeforeRouteLeave允许在组件离开当前路…...

uni-app 吸顶方案总结

效果 页面级 uni.pageScrollTo 官方文档&#xff1a;https://uniapp.dcloud.net.cn/api/ui/scroll.html#pagescrollto 原生头部导航 uni.pageScrollTo({selector: #tabs,duration: 300 });(推荐)需要兼容自定义头部导航 <template><view id"demo1" :styl…...

【C#】知识汇总

目录 1 概述1.1 GC&#xff08;Garbage Collection&#xff09;1.1.1 为什么需要GC&#xff1f;1.1.2 GC的工作原理工作原理什么是Root&#xff1f;GC算法&#xff1a;Mark-Compact 标记压缩算法GC优化&#xff1a;Generational 分代算法 1.1.3 GC的触发时间1.1.4 如何减少垃圾…...

1、Unity【基础】3D数学

3D数学 文章目录 3D数学1、数学计算公共类Mathf1、Mathf和Math2、区别3、Mathf中的常用方法&#xff08;一般计算一次&#xff09;4、Mathf中的常用方法&#xff08;一般不停计算&#xff09;练习 A物体跟随B物体移动 2、三角函数1、角度和弧度2、三角函数3、反三角函数练习 物…...

虚拟机ubuntu22的扩容记录

这里lsblk命令能看到&#xff0c; ubuntu逻辑分区只有29G&#xff0c; 但总分区60G&#xff0c;还有接近30G未使用。 rootx:/home/x# lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS loop0 7:0 0 63.9M 1 loop /snap/core2…...

Docker 常用配置

Docker 常用配置 1. 配置方法 修改下面位置&#xff1a; Linux&#xff1a;vim /etc/docker/daemon.jsonmacOS&#xff1a;菜单栏图标->Settings->Docker Engine 注意&#xff1a;修改完需要重启Docker Linux&#xff1a;systemctl restart dockermacOS&#xff1a;…...

通过示例了解 .NET Core 中的依赖注入

依赖注入 (DI) 是一种用于实现 IoC&#xff08;控制反转&#xff09;的设计模式&#xff0c;可以更好地解耦应用程序内的依赖关系并更轻松地管理它们。.NET Core 内置了对依赖注入的支持&#xff0c;提供了一种有效管理依赖关系的强大方法。 一.什么是依赖注入&#xff1f; 依…...

fetch、FormData上传多张图片

利用fetch方法和FormData对象上传多张图片 formdata()对象可以序列化多张图片 <html><head><meta http-equiv"content-type" content"text/html;charsetUTF-8"/><title>测试fetch和formdata上传多张图片</title></head&…...

C++STL详解(五)——list类的具体实现

一.本次所需实现的三个类及其成员函数接口 链表首先要有结点&#xff0c;因此我们需要实现一个结点类。 链表要有管理结点的结构&#xff0c;因此我们要有list类来管理结点。 链表中还要有迭代器&#xff0c;而迭代器的底层其实是指针。但是我们现有的结点类无法完成迭代器的…...

鸿蒙(API 12 Beta3版)【使用投播组件】案例应用

华为视频接入播控中心和投播能力概述** 华为视频在进入影片详情页播放时&#xff0c;支持在控制中心查看当前播放的视频信息&#xff0c;并进行快进、快退、拖动进度、播放暂停、下一集、调节音量等操作&#xff0c;方便用户通过控制中心来操作当前播放的视频。 当用户希望通…...

【STM32项目】在FreeRtos背景下的实战项目的实现过程(一)

个人主页~ 这篇文章是我亲身经历的&#xff0c;在做完一个项目之后总结的经验&#xff0c;虽然我没有将整个项目给放出来&#xff0c;因为这项目确实也是花了米让导师指导的&#xff0c;但是这个过程对于STM32的实战项目开发都是非常好用的&#xff0c;可以说按照这个过程&…...

C#垃圾处理机制相关笔记

C#编程中的垃圾处理机制主要通过垃圾回收器&#xff08;Garbage Collector&#xff0c;GC&#xff09;实现自动内存管理。C#作为一种托管语言&#xff0c;其垃圾处理机制显著减轻了程序员的内存管理负担&#xff0c;与C语言等非托管语言形成鲜明对比。具体介绍如下&#xff1a;…...

KubeSphere 容器平台高可用:环境搭建与可视化操作指南

Linux_k8s篇 欢迎来到Linux的世界&#xff0c;看笔记好好学多敲多打&#xff0c;每个人都是大神&#xff01; 题目&#xff1a;KubeSphere 容器平台高可用&#xff1a;环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

ES6从入门到精通:前言

ES6简介 ES6&#xff08;ECMAScript 2015&#xff09;是JavaScript语言的重大更新&#xff0c;引入了许多新特性&#xff0c;包括语法糖、新数据类型、模块化支持等&#xff0c;显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var&#xf…...

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:

一、属性动画概述NETX 作用&#xff1a;实现组件通用属性的渐变过渡效果&#xff0c;提升用户体验。支持属性&#xff1a;width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项&#xff1a; 布局类属性&#xff08;如宽高&#xff09;变化时&#…...

Oracle查询表空间大小

1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...

现代密码学 | 椭圆曲线密码学—附py代码

Elliptic Curve Cryptography 椭圆曲线密码学&#xff08;ECC&#xff09;是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础&#xff0c;例如椭圆曲线数字签…...

【决胜公务员考试】求职OMG——见面课测验1

2025最新版&#xff01;&#xff01;&#xff01;6.8截至答题&#xff0c;大家注意呀&#xff01; 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:&#xff08; B &#xff09; A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南

&#x1f680; C extern 关键字深度解析&#xff1a;跨文件编程的终极指南 &#x1f4c5; 更新时间&#xff1a;2025年6月5日 &#x1f3f7;️ 标签&#xff1a;C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言&#x1f525;一、extern 是什么&#xff1f;&…...

管理学院权限管理系统开发总结

文章目录 &#x1f393; 管理学院权限管理系统开发总结 - 现代化Web应用实践之路&#x1f4dd; 项目概述&#x1f3d7;️ 技术架构设计后端技术栈前端技术栈 &#x1f4a1; 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 &#x1f5c4;️ 数据库设…...

站群服务器的应用场景都有哪些?

站群服务器主要是为了多个网站的托管和管理所设计的&#xff0c;可以通过集中管理和高效资源的分配&#xff0c;来支持多个独立的网站同时运行&#xff0c;让每一个网站都可以分配到独立的IP地址&#xff0c;避免出现IP关联的风险&#xff0c;用户还可以通过控制面板进行管理功…...