【LeetCode】199.二叉树的右视图

news2024/11/15 11:10:02

1.问题

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

示例 1:

在这里插入图片描述

输入: [1,2,3,null,5,null,4]
输出: [1,3,4]

示例 2:

输入: [1,null,3]
输出: [1,3]

示例 3:

输入: []
输出: []

提示:

  • 二叉树的节点个数的范围是 [0,100]
  • -100 <= Node.val <= 100

2.解题思路

经历过前面几篇关于二叉树的层序遍历算法之后(参见102.二叉树的层序遍历,107.二叉树的层序遍历II),非常容易的就可以通过这种算法解答此题,基本思想就是围绕队列性质,广度优先算法解决。当然,深度优先算法也是可以解决的。

2.1 广度优先(BFS)

利用队列,遍历每层节点,并记录每层最后一个元素,直到遍历完最后一层,即可得到结果。访问顺序如下图所示:
在这里插入图片描述
红色结点自上而下组成答案,边缘以访问顺序标号。
复杂度

  • 时间复杂度: O(N),每个节点都入队出队了 1 次。
  • 空间复杂度: O(N),使用了额外的队列空间。

2.2 深度优先(DFS)

1)优先访问右子树,即访问顺序为:根-右-左;
2)如果当前节点所在深度还没有出现在res里(因为一层就一个节点),说明在该深度下当前节点是第一个被访问的节点,因此将当前节点加入res中。

if len(res) < depth:
    res.append(root.val)
# 遍历右子树
if root.right:
    dfs(root.right, depth + 1, res)
# 遍历左子树
if root.left:
    dfs(root.left, depth + 1, res)

复杂度

  • 时间复杂度: O(N),每个节点都访问了 1 次。
  • 空间复杂度: O(N),因为这不是一棵平衡二叉树,二叉树的深度最少是 logN, 最坏的情况下会退化成一条链表,深度就是N,因此递归时使用的栈空间是 O(N) 的。

3.代码

/**
 * 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 {
    /**
    	广度优先
        1.利用层序遍历思想,统计每层最后一个元素,即为答案
        2.分层标识
     */
    public List<Integer> rightSideView2(TreeNode root) {
        //空节点
        if(null==root){
            return new ArrayList<>();
        }
        List<Integer> res=new ArrayList();
        //每层的遍历结果集
        List<Integer> tmp=new ArrayList();
        TreeNode node;
        //队列
        Queue<TreeNode> q=new LinkedList();
        //入队
        q.add(root);
        //分层标识
        q.add(null);

        while(!q.isEmpty()){
            node=q.poll();
            if(null!=node){
                tmp.add(node.val);
                //左右子树入队
                if(null!=node.left){
                    q.add(node.left);
                }
                if(null!=node.right){
                    q.add(node.right);
                }
            }
            //否层,该层遍历完毕
            else{
                if(!tmp.isEmpty()){
                    //收集每层最后一个元素
                    res.add(tmp.get(tmp.size()-1));
                    tmp=new ArrayList();
                    q.add(null);
                }
            }
        }
        return res;
    }

    //深度优先,递归
    public List<Integer> rightSideView(TreeNode root) {
        //判空
        if(null==root){
            return new ArrayList();
        }
        List<Integer> res=new ArrayList();
        dfs(root, 0, res);
        return res;
    }

    private void dfs(TreeNode root, int depth, List<Integer> res){
        if(res.size()==depth){
            res.add(root.val);
        }
        //左右子树,先遍历右子树,然后左子树
        if(null!=root.right){
            dfs(root.right, depth+1, res);
        }
        if(null!=root.left){
            dfs(root.left, depth+1, res);
        }
    }
}

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

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

相关文章

类加载过程

基本说明 反射机制是Java实现动态语言的关键&#xff0c;也就是通过反射实现类动态加载。 静态加载&#xff1a;编译时加载相关的类&#xff0c;如果没有则报错&#xff0c;依赖性太强动态加载&#xff1a;运行时加载需要的类&#xff0c;如果运行时不用该类&#xff0c;即使…

C++关于线程的一些操作

线程创建和接收 std::this_thread::get_id()获取当前线程的线程ID std::this_thread::yield()让步结束当前线程的时间片 int main() {vector<thread> threads(2);threads[0] thread([]() {cout << this_thread::get_id() << endl;});threads[1] thread([](…

Baumer工业相机中偏振相机如何使用Baumer堡盟GAPI SDK来进行偏振数据的计算转换输出(C#)

项目场景 Baumer工业相机堡盟相机是一种高性能、高质量的工业相机&#xff0c;可用于各种应用场景&#xff0c;如物体检测、计数和识别、运动分析和图像处理。 Baumer的万兆网相机拥有出色的图像处理性能&#xff0c;可以实时传输高分辨率图像。此外&#xff0c;该相机还具…

ansible自动运维——ansible使用临时命令通过模块来执行任务

大家好&#xff0c;这里是天亮之前ict&#xff0c;本人网络工程大三在读小学生&#xff0c;拥有锐捷的ie和红帽的ce认证。每天更新一个linux进阶的小知识&#xff0c;希望能提高自己的技术的同时&#xff0c;也可以帮助到大家 另外其它专栏请关注&#xff1a; 锐捷数通实验&…

【机器学习实战】Python基于SVD奇异值分解进行矩阵分解(八)

文章目录 1 前言1.1 奇异值分解1.2 奇异值分解的应用 2 简单计算SVD2.1 NumPy 计算 SVD2.2 scikit-learn 计算截断 SVD2.3 scikit-learn 计算随机 SVD 3 demo数据演示3.1 导入函数3.2 导入数据3.3 计算SVD 4 讨论 1 前言 1.1 奇异值分解 奇异值分解&#xff08;Singular Valu…

信息安全复习四:置换密码乘积密码隐写术

一、章节梗概 置换密码、Rail Fence密码、行置换密码、乘积密码、转子机、隐写术 二、置换技术 2.1 定义 重新排列明文字母&#xff0c;达到信息加密的目的。 与替代密码不同的是&#xff0c;原来明文中的字母同样出现在密文中&#xff0c;只是顺序被打断。 古典的置换密码…

.net6 core Worker Service项目发布部署到Linux,以守护进程服务的形式部署启动

一、发布项目 1、以文件夹形式 2、目标运行时选对应的平台&#xff08;Linux-x64&#xff09; 3、文件夹选项&#xff1a;在发布前删除所有现有文件 二、部署项目&#xff08;安装.net6环境&#xff1a;参考Linux安装 dotnet sdk 6.0&#xff09; &#xff08;1&#xff09;…

《Spring MVC》 第二章 让程序run起来

前言 Spring MVC 是 Spring 框架提供的一款基于 MVC 模式的轻量级 Web 开发框架。 Spring MVC 本质是对 Servlet 的进一步封装&#xff0c;其最核心的组件是DispatcherServlet&#xff0c;它是 Spring MVC 的前端控制器&#xff0c;主要负责对请求和响应的统一地处理和分发。C…

用好Python自然语言工具包-- 实例“基于本地知识库的自动问答”

首先鸣谢thomas-yanxin 本问中示例来自他在GitHub上的开源项目“基于本地知识库的自动问答”&#xff0c;链接如下&#xff1a; thomas-yanxin/LangChain-ChatGLM-Webui: 基于LangChain和ChatGLM-6B的针对本地知识库的自动问答 (github.com) 目录 1. 基础知识&#xff1a; …

JVM调优最佳参数

项目背景 C端的项目&#xff0c;用户量比较多&#xff0c;请求比较多。 启动参数表 Xmx指定应用程序可用的最大堆大小。 Xms指定应用程序可用的最小堆大小。 &#xff08;一般情况下&#xff0c;需要设置Xmx和Xms为相等的值&#xff0c;且为一个固定的值&#xff09; 如果该值…

HCIP之链路聚合、VRRP

链路聚合 链路聚合 --- 可以将多个物理接口绑定成一个逻辑接口&#xff0c;即将N条物理链路聚合为一条逻辑链路。可以在不升级硬件的条件下&#xff0c;达到增加带宽的效果 我们将逻辑链路&#xff0c;称为聚合链路&#xff0c;在华为设备中称为ETH-TRUNK链路&#xff08;这个技…

Vue表单进阶操作

多选框另类使用场景 这个复选框和上面爱好那个复选框是不一样的&#xff0c;它不需要收集value值&#xff0c;只需要知道是否被选择&#xff0c;也就是ture或false&#xff0c;这时候就可以安装输入框的方式去写&#xff0c;直接去定义字符串&#xff0c;而不是数组 然后把全部…

“esp8266mod模块连接机智云Arduino实现pwm调节led的亮度“+_+

经过几天的漫长的探索和调试&#xff0c;终于连上机智云了。 历经的困难&#xff1a;esp8266总是连接机智云app超时&#xff0c;连接无反应&#xff0c;无数据。 1、机智云开发者中心&#xff0c;新建数据点&#xff0c;生成muc代码包&#xff0c;具体配置可以参考其他文章。…

go破冰之旅·5·常量、变量、数据类型

成体系的、快速学通Go&#xff0c;就在此时&#xff0c;持续连载&#xff01; 上一篇&#xff1a; https://lan6193.blog.csdn.net/article/details/123454411https://lan6193.blog.csdn.net/article/details/123454411上文熟悉了Go的基础符号、基础规则&#xff0c;本文我们…

前端项目代码规范

一、变量与函数的命名&#xff08;变量名和函数名是最好的注释&#xff09; 通常情况下函数小陀峰、类名大陀峰、变量短横线/小陀峰、const全大写单词要表达出正确的语义&#xff0c;如&#xff1a;array类型或其它集合类型用英语复数格式、其它类型不要用复数格式区分函数为功…

async/await 在 C# 语言中是如何工作的?(下)

接《async/await 在 C# 语言中是如何工作的&#xff1f;&#xff08;上&#xff09;》、《async/await 在 C# 语言中是如何工作的&#xff1f;&#xff08;中&#xff09;》&#xff0c;今天我们继续介绍 SynchronizationContext 和 ConfigureAwait。 ▌SynchronizationContext…

【SVN已解决】修改svn服务端地址为ip或者域名地址的方法

介绍 这里是小编成长之路的历程&#xff0c;也是小编的学习之路。希望和各位大佬们一起成长&#xff01; 以下为小编最喜欢的两句话&#xff1a; 要有最朴素的生活和最遥远的梦想&#xff0c;即使明天天寒地冻&#xff0c;山高水远&#xff0c;路远马亡。 一个人为什么要努力&a…

Vue之指令详解与自定义指令

指令 想要了解自定义指令&#xff0c;那肯定得先明白什么是指令。 指令的本质&#xff1a;语法糖&#xff0c;标志位。在编译阶段 render 函数里&#xff0c;会把指令编译成 JavaScript 代码。 常见的Vue内置指令有&#xff1a; v-on 即 。v-on:click”function“&#xff…

Node【Express框架【二】】

文章目录 &#x1f31f;前言&#x1f31f;中间件&#x1f31f;中间件函数&#x1f31f;什么是中间件函数&#x1f31f;中间件函数可以做什么 &#x1f31f;Express中间件的类型&#x1f31f;应用级中间件&#x1f31f;路由器级中间件&#x1f31f;错误处理中间件&#x1f31f;内…

人为惨案之kube-controller-manager 不断重启根因溯源

文章目录 背景问题发现排查CSI provision排查kube-controller-manager查看controller log紧急恢复求助chatgpt 背景 2023年4月21日10:38:07&#xff0c;在集群中测试RBAC的时候&#xff0c;在kuboard的界面神出鬼没的删除了几个clusterRole。练习一个CKA的练习题目. Create a…