二叉树的右视图[中等]

news2025/1/22 14:44:14

优质博文:IT-BLOG-CN

一、题目

给定一个二叉树的 根节点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

二、代码

由于树的形状无法提前知晓,不可能设计出优于O(n)的算法。因此,我们应该试着寻找线性时间解。带着这个想法,我们来考虑一些同等有效的方案。

【1】深度优先搜索: 我们对树进行深度优先搜索,在搜索过程中,我们总是先访问右子树。那么对于每一层来说,我们在这层见到的第一个结点一定是最右边的结点。这样一来,我们可以存储在每个深度访问的第一个结点,一旦我们知道了树的层数,就可以得到最终的结果数组。

上图表示了问题的一个实例。红色结点自上而下组成答案,边缘以访问顺序标号。

class Solution {
    public List<Integer> rightSideView(TreeNode root) {
        Map<Integer, Integer> rightmostValueAtDepth = new HashMap<Integer, Integer>();
        int max_depth = -1;

        Deque<TreeNode> nodeStack = new LinkedList<TreeNode>();
        Deque<Integer> depthStack = new LinkedList<Integer>();
        nodeStack.push(root);
        depthStack.push(0);

        while (!nodeStack.isEmpty()) {
            TreeNode node = nodeStack.pop();
            int depth = depthStack.pop();

            if (node != null) {
            	// 维护二叉树的最大深度
                max_depth = Math.max(max_depth, depth);

                // 如果不存在对应深度的节点我们才插入
                if (!rightmostValueAtDepth.containsKey(depth)) {
                    rightmostValueAtDepth.put(depth, node.val);
                }

                nodeStack.push(node.left);
                nodeStack.push(node.right);
                depthStack.push(depth + 1);
                depthStack.push(depth + 1);
            }
        }

        List<Integer> rightView = new ArrayList<Integer>();
        for (int depth = 0; depth <= max_depth; depth++) {
            rightView.add(rightmostValueAtDepth.get(depth));
        }

        return rightView;
    }
}

时间复杂度: O(n)。深度优先搜索最多访问每个结点一次,因此是线性复杂度。
空间复杂度: O(n)。最坏情况下,栈内会包含接近树高度的结点数量,占用O(n)的空间。

【2】广度优先搜索: 我们可以对二叉树进行层次遍历,那么对于每层来说,最右边的结点一定是最后被遍历到的。二叉树的层次遍历可以用广度优先搜索实现。执行广度优先搜索,左结点排在右结点之前,这样,我们对每一层都从左到右访问。因此,只保留每个深度最后访问的结点,我们就可以在遍历完整棵树后得到每个深度最右的结点。除了将栈改成队列,并去除了rightmost_value_at_depth之前的检查外,算法没有别的改动。

上图表示了同一个示例,红色结点自上而下组成答案,边缘以访问顺序标号。

class Solution {
    public List<Integer> rightSideView(TreeNode root) {
        Map<Integer, Integer> rightmostValueAtDepth = new HashMap<Integer, Integer>();
        int max_depth = -1;

        Queue<TreeNode> nodeQueue = new LinkedList<TreeNode>();
        Queue<Integer> depthQueue = new LinkedList<Integer>();
        nodeQueue.add(root);
        depthQueue.add(0);

        while (!nodeQueue.isEmpty()) {
            TreeNode node = nodeQueue.remove();
            int depth = depthQueue.remove();

            if (node != null) {
            	// 维护二叉树的最大深度
                max_depth = Math.max(max_depth, depth);

                // 由于每一层最后一个访问到的节点才是我们要的答案,因此不断更新对应深度的信息即可
                rightmostValueAtDepth.put(depth, node.val);

                nodeQueue.add(node.left);
                nodeQueue.add(node.right);
                depthQueue.add(depth + 1);
                depthQueue.add(depth + 1);
            }
        }

        List<Integer> rightView = new ArrayList<Integer>();
        for (int depth = 0; depth <= max_depth; depth++) {
            rightView.add(rightmostValueAtDepth.get(depth));
        }

        return rightView;
    }
}

时间复杂度: O(n)。每个节点最多进队列一次,出队列一次,因此广度优先搜索的复杂度为线性。
空间复杂度: O(n)。每个节点最多进队列一次,所以队列长度最大不不超过n,所以这里的空间代价为O(n)

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

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

相关文章

强化学习第1天:强化学习概述

☁️主页 Nowl &#x1f525;专栏《机器学习实战》 《机器学习》 &#x1f4d1;君子坐而论道&#xff0c;少年起而行之 ​​ 文章目录 介绍 强化学习要素 强化学习任务示例 环境搭建&#xff1a;gym 基本用法 环境信息查看 创建智能体 过程可视化 完整代码 结语…

0基础学java-day15

一、泛型 1 泛型的理解和好处 1.1 看一个需求 【不小心加入其它类型&#xff0c;会导致出现类型转换异常】 package com.hspedu.generic;import java.util.ArrayList;/*** author 林然* version 1.0*/ public class Generic01 {SuppressWarnings("all")public st…

企业数字档案馆室建设指南

数字化时代&#xff0c;企业数字化转型已经成为当下各行业发展的必然趋势。企业数字化转型不仅仅是IT系统的升级&#xff0c;也包括企业内部各种文件、档案、合同等信息的数字化管理。因此&#xff0c;建设数字档案馆室也变得尤为重要。本篇文章将为您介绍企业数字档案馆室建设…

SpringMVC修炼之旅(2)基础入门

一、第一个程序 1.1环境配置 略 1.2代码实现 package com.itheima.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody;//定义…

初识MQ——消息队列技术选型

文章目录 同步和异步通讯同步通讯异步通讯 技术对比 同步和异步通讯 微服务间通讯有同步和异步两种方式&#xff1a; 同步通讯&#xff1a;就像打电话&#xff0c;需要实时响应。 异步通讯&#xff1a;就像发邮件&#xff0c;不需要马上回复。 两种方式各有优劣&#xff0c…

CCF编程能力等级认证GESP—C++1级—20230318

CCF编程能力等级认证GESP—C1级—20230318 单选题&#xff08;每题 2 分&#xff0c;共 30 分&#xff09;判断题&#xff08;每题 2 分&#xff0c;共 20 分&#xff09;编程题 (每题 25 分&#xff0c;共 50 分)每月天数长方形面积 答案及解析单选题判断题编程题1编程题2 单选…

SQL手工注入漏洞测试(Sql Server数据库)-墨者

———靶场专栏——— 声明&#xff1a;文章由作者weoptions学习或练习过程中的步骤及思路&#xff0c;非正式答案&#xff0c;仅供学习和参考。 靶场背景&#xff1a; 来源&#xff1a; 墨者学院 简介&#xff1a; 安全工程师"墨者"最近在练习SQL手工注入漏洞&#…

国内AI翘楚,看看有没有你心动的offer?

科技创新争占高地&#xff0c;AI领域各显神通。从一战成名的阿尔法狗到引起轩然大波的ChatGPT&#xff0c;我们早已卷入了一场没有硝烟的革命。前方世人看到的科技日新日异、岁月静好&#xff0c;后方是各大企业的绞尽脑汁、争先恐后。人工智能时代&#xff0c;AI是挡不住的时代…

Lebesgue积分及应用

Lebesgue积分及应用 文章目录 Lebesgue积分及应用一、Lebesgue测度和可测函数1.1 Riemann积分和Lebesgue积分1.2 直线上的Lebesgue测度【定义】外测度&#xff08;Outer Measure&#xff09;【定理】外测度的性质【定义】内测度【定义】可测、Lebesgue测度【定理】卡氏条件&…

Java注册并监听全局快捷键

背景 之前在博客中分享了SWT托盘功能, 随之带来一个问题, 当程序最小化后无法快速唤醒, 按照平时使用软件的思路, 自然想到了注册全局快捷键, 本文介绍使用java方式实现全局快捷键的注册. 方案 通过google,搜到一个现成的库: jintellitype, 使用maven可以直接引用, 非常方便…

C语言易错知识点八(整形与浮点型在内存中存储的实质)

整形与浮点型在内存中存储的实质 当我们在刷抖音或者其他短视频平台时&#xff0c;可能会时不时(总是&#xff0c;我相信大家肯定是不会被外表骗到的那一类人ヾ(●゜ⅴ゜)&#xff89;)刷到各种帅哥美女的视频&#xff0c;或者我们在学校里看到帅哥美女时&#xff0c;如果我们只…

NFC和蓝牙在物联网中有什么意义?如何选择?

#NFC物联网# #蓝牙物联网# 在物联网中&#xff0c;NFC和蓝牙有什么意义&#xff1f; NFC在物联网中代表近场通信技术。它是一种短距离、高频的无线通信技术&#xff0c;可以在近距离内实现设备间的数据传输和识别。NFC技术主要用于移动支付、电子票务、门禁、移动身份识别、防…

Vue2中v-html引发的安全问题

前言&#xff1a;v-html指令 1.作用&#xff1a;向指定节点中渲染包含html结构的内容。 2.与插值语法的区别&#xff1a; (1).v-html会替换掉节点中所有的内容&#xff0c;{{xx}}则不会。 (2).v-html可以识别html结构。 3.严重注意&#xff1a;v-html有安全性问题&#xff0…

STM32串口接收数据包(自定义帧头帧尾)

1、基本概述 本实验基于stm32c8t6单片机&#xff0c;串口作为基础且重要的外设&#xff0c;具有广泛的应用。本文主要理解串口数据包的发送与接收是如何实现的&#xff0c;重要的是理解程序的实现思路。 2、关键程序 定义好需要用到的变量&#xff1a; uint8_t rxd_buf[4];//…

湖南麒麟下默认使用串口输出系统日志

有时候为了调试方便&#xff0c;需要将系统日志通过CPU的串口进行输出&#xff0c;以下是针对至强E5V4处理器上安装湖南麒麟操作系统后将日志通过串口输出的配置。 首先在bios中打开串口重定向功能&#xff0c;这里的BIOS是AMI的BIOS 内部配置如下&#xff0c;波特率115200配置…

ESP32网络开发实例-发送邮件

发送邮件 文章目录 发送邮件1、邮件发送配置2、软件准备3、硬件准备4、代码实现本文将详细介绍在ESP32中如何使用SMTP协议发送邮件。 1、邮件发送配置 在本次实例中,我们将通过QQ邮箱向指定邮件地址发送邮件。 第一步,注册QQ邮箱 第二步,开启QQ邮箱SMTP/IMAP 服务: 生成…

一文搞懂Git版本控制系统

1. Git简介 当涉及到软件开发或协作时&#xff0c;版本管理是一个不可或缺的概念。无论你是一个独立开发者还是一个团队成员&#xff0c;都会遇到需要跟踪和管理代码变更的情况。这时候&#xff0c;Git作为一个强大而流行的版本控制系统就发挥着重要的作用。 Git&#xff08;读…

使用Pytoch实现Opencv warpAffine方法

随着深度学习的不断发展&#xff0c;GPU/NPU的算力也越来越强&#xff0c;对于一些传统CV计算也希望能够直接在GPU/NPU上进行&#xff0c;例如Opencv的warpAffine方法。Opencv的warpAffine的功能主要是做仿射变换&#xff0c;如果不了解仿射变换的请自行了解。由于Pytorch的图像…

每日一题:LeetCode-75. 颜色分类

每日一题系列&#xff08;day 12&#xff09; 前言&#xff1a; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f50e…

【多线程】线程的三种常见创建方式

文章目录 线程创建方式1——Thread线程创建方式2——Runnable线程创建方式2——匿名内部类线程创建方式3——Callable、FutureTask,带返回值 线程其实是程序中的一条执行路径。 那怎样的程序才是多线程程序呢&#xff1f; 例如12306网站就是支持多线程的&#xff0c;因为同时可…