当前位置: 首页 > 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;…...

PHP和Node.js哪个更爽?

先说结论&#xff0c;rust完胜。 php&#xff1a;laravel&#xff0c;swoole&#xff0c;webman&#xff0c;最开始在苏宁的时候写了几年php&#xff0c;当时觉得php真的是世界上最好的语言&#xff0c;因为当初活在舒适圈里&#xff0c;不愿意跳出来&#xff0c;就好比当初活在…...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者

抖音增长新引擎&#xff1a;品融电商&#xff0c;一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中&#xff0c;品牌如何破浪前行&#xff1f;自建团队成本高、效果难控&#xff1b;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

c++ 面试题(1)-----深度优先搜索(DFS)实现

操作系统&#xff1a;ubuntu22.04 IDE:Visual Studio Code 编程语言&#xff1a;C11 题目描述 地上有一个 m 行 n 列的方格&#xff0c;从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子&#xff0c;但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

Java - Mysql数据类型对应

Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...

五年级数学知识边界总结思考-下册

目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解&#xff1a;由来、作用与意义**一、知识点核心内容****二、知识点的由来&#xff1a;从生活实践到数学抽象****三、知识的作用&#xff1a;解决实际问题的工具****四、学习的意义&#xff1a;培养核心素养…...

Java 加密常用的各种算法及其选择

在数字化时代&#xff0c;数据安全至关重要&#xff0c;Java 作为广泛应用的编程语言&#xff0c;提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景&#xff0c;有助于开发者在不同的业务需求中做出正确的选择。​ 一、对称加密算法…...

有限自动机到正规文法转换器v1.0

1 项目简介 这是一个功能强大的有限自动机&#xff08;Finite Automaton, FA&#xff09;到正规文法&#xff08;Regular Grammar&#xff09;转换器&#xff0c;它配备了一个直观且完整的图形用户界面&#xff0c;使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...

HashMap中的put方法执行流程(流程图)

1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中&#xff0c;其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下&#xff1a; 初始判断与哈希计算&#xff1a; 首先&#xff0c;putVal 方法会检查当前的 table&#xff08;也就…...

关于easyexcel动态下拉选问题处理

前些日子突然碰到一个问题&#xff0c;说是客户的导入文件模版想支持部分导入内容的下拉选&#xff0c;于是我就找了easyexcel官网寻找解决方案&#xff0c;并没有找到合适的方案&#xff0c;没办法只能自己动手并分享出来&#xff0c;针对Java生成Excel下拉菜单时因选项过多导…...