【面试经典 150 | 二叉树层序遍历】二叉树的右视图

news2025/1/19 8:04:34

文章目录

  • 写在前面
  • Tag
  • 题目来源
  • 解题思路
    • 方法一:层序遍历
    • 方法二:深度优先搜索
  • 写在最后

写在前面

本专栏专注于分析与讲解【面试经典150】算法,两到三天更新一篇文章,欢迎催更……

专栏内容以分析题目为主,并附带一些对于本题涉及到的数据结构等内容进行回顾与总结,文章结构大致如下,部分内容会有增删:

  • Tag:介绍本题牵涉到的知识点、数据结构;
  • 题目来源:贴上题目的链接,方便大家查找题目并完成练习;
  • 题目解读:复述题目(确保自己真的理解题目意思),并强调一些题目重点信息;
  • 解题思路:介绍一些解题思路,每种解题思路包括思路讲解、实现代码以及复杂度分析;
  • 知识回忆:针对今天介绍的题目中的重点内容、数据结构进行回顾总结。

Tag

【二叉树】【层序遍历】【深搜】【广搜】


题目来源

199. 二叉树的右视图


解题思路

方法一:层序遍历

思路

使用层序遍历的方法,返回二叉树每一层的最后一个节点。

如果对于层序遍历知识不熟悉,可以参考 广度优先搜索(1)之树的层序遍历 和 【二叉树的四种遍历——前序、中序、后续和层序遍历】。

算法

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
	vector<int> rightSideView(TreeNode* root) {
		vector<int> res;
		if (root == NULL)
			return res;

		queue<TreeNode*> q;
		q.push(root);

		while (!q.empty()) {
			int size = q.size();
            TreeNode *node = nullptr;
			while(size--)  {
				node = q.front();
				q.pop();
                if (node->left) q.push(node->left);
				if (node->right) q.push(node->right);
			}
            res.emplace_back(node->val);
		}
		return res;
	}
};

复杂度分析

时间复杂度: O ( n ) O(n) O(n) n n n 是二叉树中的节点数,每个节点最多入队出队各一次。

空间复杂度: O ( n ) O(n) O(n)

方法二:深度优先搜索

思路

我们对树进行深度优先搜索,在搜索的过程中需要总是先访问右子树。那么对于每一层来说,我们在这层看到的第一个节点及就是一定是最右边的节点。

如何保证总是先访问右子树?利用栈的后进先出的特点,依次将当前节点的左、右节点压入栈中,那么栈中弹出的节点顺序就是先右再左子节点了。

如何实现 我们在这层看到的第一个节点及就是一定是最右边的节点 ?维护一个表示层深的局部变量,以此作为哈希表的键,二叉树当前层深所在层的最后节点值作为哈希表的值。

只有当前层深未曾出现在哈希表时,才更新哈希表,这样加上利用栈存放节点,便可以保证 “我们在这层看到的第一个节点及就是一定是最右边的节点”。

代码

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    vector<int> rightSideView(TreeNode* root) {
        unordered_map<int, int> mostRNodeDepth2Val;
        int maxDepth = -1;

        stack<TreeNode*> nodeStk;   // 节点栈
        stack<int> depthStk;        // 与节点对应的深度栈
        nodeStk.push(root);
        depthStk.push(0);

        while (!nodeStk.empty()) {
            TreeNode* node = nodeStk.top(); nodeStk.pop();
            int depth = depthStk.top(); depthStk.pop();

            if (node != nullptr) {
                maxDepth = max(maxDepth, depth);

                // 不存在对应深度的节点,我们才插入
                if (mostRNodeDepth2Val.find(depth) == mostRNodeDepth2Val.end()) {
                    mostRNodeDepth2Val[depth] = node->val;
                }

                nodeStk.push(node->left);
                nodeStk.push(node->right);
                depthStk.push(depth + 1);
                depthStk.push(depth + 1);
            }
        }

        vector<int> rightView;
        for (int depth = 0; depth <= maxDepth; ++depth) {
            rightView.push_back(mostRNodeDepth2Val[depth]);
        }
        return rightView;
    }
};

复杂度分析

时间复杂度: O ( n ) O(n) O(n),深搜最多访问每个节点一次。

空间复杂度: O ( n ) O(n) O(n),最坏情况下,栈内包含接近树高度的节点数量,占用 O ( n ) O(n) O(n) 空间。


写在最后

如果您发现文章有任何错误或者对文章有任何疑问,欢迎私信博主或者在评论区指出 💬💬💬。

如果大家有更优的时间、空间复杂度的方法,欢迎评论区交流。

最后,感谢您的阅读,如果有所收获的话可以给我点一个 👍 哦。

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

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

相关文章

MySQL-使用CPP接入到MySQL

&#x1f4df;作者主页&#xff1a;慢热的陕西人 &#x1f334;专栏链接&#xff1a;MySQL &#x1f4e3;欢迎各位大佬&#x1f44d;点赞&#x1f525;关注&#x1f693;收藏&#xff0c;&#x1f349;留言 本博客主要内容介绍如何在c/cpp代码连接和管理数据库 文章目录 MySQL-…

SpringBoot-自定义注解AOP实现及拦截器示例

SpringBoot-自定义注解AOP实现及拦截器示例 一、四大元注解 当你在编写自定义注解时&#xff0c;Target、Retention、Documented 和 Inherited 是四个你可能会用到的元注解&#xff0c;它们可以帮助你更好地定义和使用注解。 1、Target Target 注解用于指定注解可以应用的程…

响应式修改 页面字体字号【大 中 小 】

浅浅记录下&#xff0c;工作中遇到的问题&#xff0c;修改页面文本字号。 <p class"change_fontSize">[ 字号 <a href"javascript:doZoom(18)">大</a><a href"javascript:doZoom(16)">中</a><a href"ja…

Java精品项目--第8期基于SpringBoot的宠物用品商城的设计分析与实现

项目使用技术栈 SpringBootThymeleafMyBatisMySQLAopJavajdk1.8 项目介绍 项目截图

嘉立创EDA基础

一&#xff0c;原理图部分 &#xff08;1&#xff09;路径设置 打开嘉立创以后&#xff0c;在右上角点击设置 可以看到下图 左边栏所有工程为工程路径&#xff0c;常用库为库路径 &#xff08;2&#xff09;模式设置 同样点击设置&#xff0c;可以看到下面界面 下图为在线系…

【读点论文】YOLOX: Exceeding YOLO Series in 2021,无锚框单阶段目标检测方案,解耦检测头的分类和回归分支,优化标签分配策略

YOLOX: Exceeding YOLO Series in 2021 Abstract 在本报告中&#xff0c;我们介绍了YOLO系列的一些经验改进&#xff0c;形成了一种新的高性能探测器—YOLOX。我们将YOLO检测器切换到无锚方式&#xff0c;并进行其他先进的检测技术&#xff0c;即去耦头和领先的标签分配策略S…

【Java EE】依赖注入DI详解

文章目录 &#x1f334;什么是依赖注入&#x1f340;依赖注入的三种方法&#x1f338;属性注入(Field Injection)&#x1f338;构造方法注入&#x1f338;Setter注入&#x1f338;三种注入优缺点分析 &#x1f333;Autowired存在的问题&#x1f332;解决Autowired对应多个对象问…

Compose Canvas

文章目录 Compose Canvas概述Canvas属性drawPoints 绘制点drawPoints属性使用 drawLine 绘制线drawLine属性使用 drawRect 绘制矩形drawRect属性使用 drawRoundRect 绘制圆角矩形drawRoundRect属性使用 drawCircle 绘制圆drawCircle属性使用 drawOval 绘制椭圆drawOval属性使用…

【宝德PI300T G2智能小站开发教程(三)】centos配置系统开发源

目录 一.前言 二.配置dns服务器 三.测试连通性 四.设置更新源文件 一.前言 openeular系统的宝德板子没有更新的国内源,要如何配置? 二.配置dns服务器 vi /etc/resolv.conf 添加如下内容: nameserver 8.8.8.8 nameserver 114.114.114.114 三.测试连通性 ping www.ba…

Python教学入门:流程控制

条件语句&#xff08;if 语句&#xff09;&#xff1a; 条件语句用于根据条件的真假执行不同的代码块。 x 10if x > 0: # 如果 x 大于 0print("x 是正数") # 输出&#xff1a;x 是正数 elif x 0: # 如果 x 等于 0print("x 是零") else: # 如果以…

【C语言】每日一题,快速提升(7)!

&#x1f525;博客主页&#x1f525;&#xff1a;【 坊钰_CSDN博客 】 欢迎各位点赞&#x1f44d;评论✍收藏⭐ 题目&#xff1a;X图形 示例&#xff1a; 输入&#xff1a; 5 //几行数输出&#xff1a; …

【GlobalMapper精品教程】074:从Lidar点云创建3D地形模型

本文基于地形点云数据,基于泊松方法、贪婪三角形测量方法和阿尔法形状创建3d地形模型。 文章目录 一、加载地形点云数据二、创建三维地形模型1. 泊松方法2. 贪婪三角形测量方法3. 阿尔法形状注意事项一、加载地形点云数据 加载配套案例数据包中的data074.rar中的地形点云数据…

【C语言】【数据结构】项目实践——贪吃蛇游戏(超详细)

前言 本篇博客我们来实现一个小游戏项目——贪吃蛇&#xff0c;相信肯定很多人都玩过&#xff0c;那么整个贪吃蛇是怎么实现出来的那&#xff0c;这个项目用到了很多方面的知识&#xff1a;C语言函数、枚举、结构体、动态内存管理、预处理指令、链表、Win32 API等。我们就通过这…

《QT实用小工具·三十二》九宫格炫酷主界面

1、概述 源码放在文章末尾 项目实现了九宫格炫酷主界面&#xff0c;下面是项目demo演示&#xff1a; 项目部分代码如下&#xff1a; #pragma execution_character_set("utf-8")#include "frmmain.h" #include "ui_frmmain.h"frmMain::frmMain…

DeepWalk论文精读

介绍 图神经网络的开山之作 DeepWalk&#xff1a;一种用于学习网络中顶点的潜在表示的新方法&#xff0c;使用随机行走中获得的局部信息&#xff0c;通过将序列视为句子&#xff0c;节点视为单词 通过随机游走可以采样出一个序列&#xff0c;序列好比一句话&#xff0c;节点…

postgresql数据库pg_dirtyread插件闪回技术 —— 筑梦之路

闪回查询&#xff08;Flashback Query&#xff09;是一种在数据库中执行时间点查询的技术。它允许查询数据库中过去某个时间点的数据状态&#xff0c;并返回相应的查询结果。通常闪回查询分为表级以及行级的闪回查询。PostgreSQL数据库由于MVCC的机制&#xff0c;对于DML的操作…

初学python记录:力扣1883. 准时抵达会议现场的最小跳过休息次数

题目&#xff1a; 给你一个整数 hoursBefore &#xff0c;表示你要前往会议所剩下的可用小时数。要想成功抵达会议现场&#xff0c;你必须途经 n 条道路。道路的长度用一个长度为 n 的整数数组 dist 表示&#xff0c;其中 dist[i] 表示第 i 条道路的长度&#xff08;单位&…

怎么配置python

右键点击“计算机”&#xff0c;选择“属性”。 在左侧栏找到“高级系统设置”。 点击“环境变量”。 在系统变量中&#xff0c;双击“Path”。 在字符串的末尾&#xff0c;加一个分号; 然后再输入你安装python的路径&#xff0c;如图所示&#xff1a; 点击“确定”&#xff0…

使用Docker搭建一主二从的redis集群

文章目录 一、根据基础镜像构建三个docker容器二、构建master机三、配置slave机四、测试 本文使用 主机指代 物理机、 master机指代“一主二从”中的 一主&#xff0c; slave机指代“一主二从”中的 二从 一、根据基础镜像构建三个docker容器 根据本文第一章&#xff08…