二叉树的右视图,力扣

目录

题目:

我们直接看题解吧:

快速理解解题思路小建议:

审题目+事例+提示:

解题方法:

解题分析:

解题思路:

代码实现(DFS):

代码1:

补充说明:

代码2:

代码实现(BFS):


题目地址:

199. 二叉树的右视图 - 力扣(LeetCode)

难度:中等

今天刷二叉树的右视图,大家有兴趣可以点上面链接,看看题目要求,试着做一下

题目:

给定一个二叉树的 根节点 root,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。

我们直接看题解吧:

快速理解解题思路小建议:

可以先简单看一下解题思路,然后照着代码看思路,会更容易理解一些。

审题目+事例+提示:

根据题意可知,我们右视图看到的节点都是每一层的最右边的节点,而这个节点可能在右子树,也可能子左子树

解题方法:

方法1:深度优先(DFS)

方法2:广度优先(BFS)

解题分析:

我们利用深度优先算法递归遍历二叉树,按照【根节点->右子树->左子树】的顺序访问。

解题思路:

 创建一个list集合res用于存储右视图看到的节点(即每层最右边的节点)

 创建一个临时遍历depth,用于记录遍历树的深度

 递归函数:

     首先判断如果根节点为Null,则直接返回

    接着判断depth与res.size是否相等,相等则将当前节点加入res

   然后depth++,遍历右子树、左子树

代码实现(DFS):

代码1:
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
 //DFS深度优先算法
class Solution {
    //先创建一个list集合存储数据作为返回
    List<Integer> res = new ArrayList<Integer>();
 
    public List<Integer> rightSideView(TreeNode root) {
        //传入根节点root,以及0(即depth初始为0)
        dfs(root,0);
        return res;
    }
 
    public void dfs(TreeNode root,int depth){
    //先判断,1、根节点是否为null,如果根节点为null则返回,
   //       2、同时也是递归的终止条件,即访问到叶子结点的下一个的时候为null,则返回
        if(root == null){
            return;
        }
 
        //首先先访问当前结点,再递归地访问右子树 和 左子树

        if(depth == res.size()){//判断二者是否相等,相等则将当前节点加入集合res
            res.add(root.val);
        }
       
      //每递归一次就说明走到下一层,即深度+1
        depth++;
 
        //先递归右子树,再递归左子树,这样每一层都能访问到最右边的结点
        dfs(root.right,depth);
        dfs(root.left,depth);
    }
}
补充说明:

1、递归函数第一部分的判空操作的作用

    a.根节点判空条件,即如果根节点为null则返回,
    b.作为递归的终止条件,即访问到叶子结点的下一个的时候为null,则返回

2、实际上遍历完右子树,回过头遍历左子树的时候,depth实际上是从头计算的,因为一开始遍历右子树时,每一次递归depth+1,那么最后回溯时depth相当于depth+1直到根节点

2、为什么depth==res.size时,就将当前节点添加到集合res(还是无法理解可以看看下面代码2)

以此图为例

首先遍历右子树,depth和res.size初始值均为0,根据代码自上而下的执行顺序,res.size首先+1即添加根节点,接着时depth+1,进入下一层,此时res.size==depth==1,因此添加当前节点,接着depth+1...

遍历完右子树后,遍历左子树,由于depth从0开始,在同一层时,depth与res.size差1,这样就可以更新新的节点(即depth!=res.size时说明这一层已经有值在res了),同时又能保证每一层只会取到一个节点,(此外由于遍历顺序为根右左,因此保证了每层最先遍历的时最右边的节点)

代码2:

这个的跟上面区别在于用了两个变量,一个变量maxDepth记录已探索到的最大深度,和当前的深度depth,只有depth>maxDepth才往list里面add即可。这种可能更好理解一点

 class Solution {//0ms 100% On O1
    int maxHigh = 0;
    List<Integer> res = new ArrayList<Integer>();
    public List<Integer> rightSideView(TreeNode root) {
        dfs(root,1);
        return res;
    }
    public void dfs(TreeNode root,int high){
        if(root == null) return;
        if(maxHigh < high){
            res.add(root.val);
            maxHigh = high;
        }
        dfs(root.right,high+1);
        dfs(root.left,high+1);
    }
}

代码实现(BFS):

这里BFS实际上是层次遍历,然后将每层的最后一个节点加入集合

还有就是创建了一个队列queue用于存储每层遍历的节点

层次遍历-->二叉树的层序遍历,力扣-CSDN博客

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<Integer> rightSideView(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        if (root == null) {
            return res;
        }
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty()) {
            int size = queue.size();
            for (int i = 0; i < size; i++) {
                TreeNode node = queue.poll();
                if (node.left != null) {
                    queue.offer(node.left);
                }
                if (node.right != null) {
                    queue.offer(node.right);
                }
                if (i == size - 1) {  //将当前层的最后一个节点放入结果列表
                    res.add(node.val);
                }
            }
        }
        return res;
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

XUbuntu22.04之如何定制:已经绑定的快捷键?(二百一十五)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

挑战杯 基于深度学习的中文情感分类 - 卷积神经网络 情感分类 情感分析 情感识别 评论情感分类

文章目录 1 前言2 情感文本分类2.1 参考论文2.2 输入层2.3 第一层卷积层&#xff1a;2.4 池化层&#xff1a;2.5 全连接softmax层&#xff1a;2.6 训练方案 3 实现3.1 sentence部分3.2 filters部分3.3 featuremaps部分3.4 1max部分3.5 concat1max部分3.6 关键代码 4 实现效果4.…

Linux/Docker 修改系统时区

目录 1. Linux 系统1.1 通过 timedatectl 命令操作1.2 直接修改 /etc/localtime 文件 2. Docker 容器中的 Linux 操作环境&#xff1a; CentOS / AlmaOSMySQL Docker 镜像 1. Linux 系统 1.1 通过 timedatectl 命令操作 使用 timedatectl list-timezones 命令列出可用的时区…

HM2019改变粘合层网格厚度的方法

如图所示&#xff0c;这里需要改变黄色层的厚度&#xff0c;改变效果如下 操作步骤&#xff1a;

golang实现openssl自签名双向认证

第一步&#xff1a;生成CA、服务端、客户端证书 1. 生成CA根证书 生成CA证书私钥 openssl genrsa -out ca.key 4096创建ca.conf 文件 [ req ] default_bits 4096 distinguished_name req_distinguished_name[ req_distinguished_name ] countryName …

【网站项目】137微博系统网站

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

PowerBI怎么修改数据库密码

第一步&#xff1a;点击转换数据 第二步&#xff1a;点击数据源设置 第三步&#xff1a;点击编辑权限 第四步&#xff1a;点击编辑 第五步&#xff1a;输入正要修改的密码就可以了

WebStorm激活与安装(全网最快捷、最靠谱的方法)

前言&#xff1a; 相信很多小伙伴已经开始了前端的学习之旅&#xff0c;想要更快乐的学习当然少不了WebStorm这个得力的开发工具软件。但是WebStorm是付费的&#xff0c;免费版功能有太少&#xff0c;怎么才能既免费&#xff0c;又能使用上正式版呢&#xff01;当然还是激活啦…

Java:JVM基础

文章目录 参考JVM内存区域程序计数器虚拟机栈本地方法栈堆方法区符号引用与直接引用运行时常量池字符串常量池直接内存 参考 JavaGuide JVM内存区域 程序计数器 程序计数器是一块较小的内存空间&#xff0c;可以看做是当前线程所执行的字节码的行号指示器&#xff0c;各线程…

C++之结构体以及通讯录管理系统

1&#xff0c;结构体基本概念 结构体属于自定义的数据概念&#xff0c;允许用户存储不同的数据类型 2&#xff0c;结构体的定义和使用 语法&#xff1a;struct 结构体名{ 结构体成员列表}&#xff1b; 通过结构体创建变量的方式有三种&#xff1a; 1&#xff0c;struct …

一副耳机如何同时连接两台设备?双设备连接教学,耳机流转自如

或是夜深的宿舍、或是安静的图书馆……当你戴着耳机怡然自得地用平板煲着剧&#xff0c;手机突然来电&#xff0c;划破宁静的铃声想必让你尴尬无比、手忙脚乱。 想避免这种尴尬&#xff0c;其实也很简单&#xff0c;只需要使用华为的双设备连接的功能&#xff0c;即可“一副耳…

nosql的注入

一、SQL注入数据库分类 关系型数据库 mysql oracle sqlserver 非关系型数据库 key-value redis MongoDB&#xff08;not only sql&#xff09; 二、MongoDB环境搭建 自己官网下载 Download MongoDB Community Server | MongoDB 其中Mongod.exe是它的一个启动 加上数据库&…

Amazon Q :企业级的对话智能导航

前言 目前市面上的许多 AI 智能助手主要局限于开发者和一般用户的使用&#xff0c;对于企业级开发的支持相对较少。然而&#xff0c;随着时代的发展&#xff0c;针对企业发展的定制化 AI 解决方案变得愈发重要。 亚马逊云科技开发者社区为开发者们提供全球的开发技术资源。这里…

arm板运行程序时寻找动态库的路径设置

问题&#xff1a;error while loading shared libraries: libQt5Widgets.so.5: cannot open shared object file&#xff1f; 第一种方法---- 解决&#xff1a; ①复制需要用到的arm库到板子上。 ②pwd指令获取该库的绝对路径&#xff0c;把路径复制到/etc/ld.so.conf文件 ③输…

c++ 基于范围的for循环详解

在for循环中基于复杂对象我们使用引用&#xff0c;这样可以避免对象拷贝&#xff0c;提升性能。 如果确认不会修改引用对象&#xff0c;请在前面加上const限定符。帮助编译器生成更加高效的代码。 如果是基础类型&#xff0c;直接使用值即可。 C11引入了一种更简洁、统一的循…

每日一题——LeetCode1572.矩阵对角线元素的和

方法一 遍历矩阵 如果矩阵中某个位置&#xff08;x,y&#xff09;处于对角线上&#xff0c;那么这个位置必定满足&#xff1a; xy 或 xy len-1 &#xff08;len为矩阵长度&#xff09; var diagonalSum function(mat) {let len mat.length;let sum 0;for (let i 0; i …

STM32-BKP备份寄存器和RTC时钟

BKP介绍 BKP(Bckup Registers&#xff09;备份寄存器 备份寄存器是42个16位的寄存器&#xff0c;可用来存储84个字节的用户应用程序数据。他们处在备份域里&#xff0c;当VDD电源被切断&#xff0c;他们仍然由VBAT&#xff08;备用电池电源&#xff09;维持供电。当系统在待机…

2024绿色能源、城市规划与环境国际会议(ICGESCE 2024)

2024绿色能源、城市规划与环境国际会议(ICGESCE 2024) 一、【会议简介】 随着全球气候变化和环境问题日益严重&#xff0c;绿色能源和可持续发展已成为全球关注的焦点。本次会议旨在汇聚全球在绿色能源、城市规划与环境领域的专家、学者和实践者&#xff0c;共同探讨和分享关于…

冒泡排序 和 qsort排序

目录 冒泡排序 冒泡排序部分 输出函数部分 主函数部分 总代码 控制台输出显示 总代码解释 冒泡排序优化 冒泡排序 主函数 总代码 代码优化解释 qsort 排序 qsort 的介绍 使用qsort排序整型数据 使用qsort排序结构数据 冒泡排序 首先&#xff0c;我先介绍我的冒泡…

wordpress 开源主题

海外就医wordpress主题 出国看病、海外就医是越来越多中产家庭的选择&#xff0c;此wordpress主题适合做相关业务的公司官网。 https://www.jianzhanpress.com/?p5220 防护wordpress外贸主题 个人防护器具wordpress外贸主题&#xff0c;适合做劳动保护的外贸公司使用。 ht…