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

news/2024/7/20 22:21:02 标签: leetcode, 深度优先, 算法, 广度优先

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.niftyadmin.cn/n/254047.html

相关文章

java_java基础语法

注释 什么是注释 简单来说注释就是在程序中对代码进行解释说明的文字,方便自己和其他人理解,查看,不会影响程序的正常执行注释有哪些 单行注释// 注释内容只能写一行多行注释/* 注释内容1 注释内容2 */文档注释/** 注释内容 注释内容 */字面量 告诉程序员,数据在程序中的书写…

JDBC操作数据库

数据库介绍 数据库是一种存储结构&#xff0c;允许使用各种格式输入、处理和检索数据&#xff0c;不必再每次需要数据时重新输入。当前比较流行的数据库主要有MySQL、Oracle、SQL Server等 使用JDBC操作数据库&#xff0c;SQL语句是比不可少的&#xff0c;SQL是一种结构化查询…

使用@Import注解给容器中快速导入一个组件

注册bean的方式 向Spring容器中注册bean通常有以下几种方式&#xff1a; 包扫描给组件标注注解&#xff08;Controller、Servcie、Repository、Component&#xff09;&#xff0c;但这种方式比较有局限性&#xff0c;局限于我们自己写的类Bean注解&#xff0c;通常用于导入第…

【微服务笔记18】微服务组件之Gateway实现服务限流(计数器算法、漏桶算法、令牌桶算法)

这篇文章&#xff0c;主要介绍微服务组件之Gateway实现服务限流&#xff08;计数器算法、漏桶算法、令牌桶算法&#xff09;。 目录 一、服务限流 1.1、几种限流算法 &#xff08;1&#xff09;计数器算法 &#xff08;2&#xff09;漏桶算法 &#xff08;3&#xff09;令…

战争教育策略游戏 MiracleGame,开启新阶段重塑生态和玩法

香港 Web3 区块链周刚刚在一片喧嚣中结束。各路大V、KOL 们的 report 都对 GameFi 的前景非常自信。2021-2023年期间&#xff0c;大量资金涌入 GameFi 赛道&#xff0c;GameFi 一旦爆发将会是现象级的出圈事件。 MiracleGame 是一款基于 BNB Chain 构建的英雄和元神主题的战争教…

低代码产品如何分类,大部分人都没有搞清楚

最近许多技术峰会都出现了低代码这个名词&#xff0c;可以说&#xff0c;低代码是中台之后&#xff0c;又一个热门话题和名词了。 一、什么是低代码平台&#xff1f; 低代码平台是无需编码或通过少量代码就可以快速生成应用程序的开发平台。也是一款图形化、拖拉拽方式快速实…

【Java网络编程】Socket套接字

哈喽&#xff0c;大家好~我是你们的老朋友&#xff1a; 保护小周ღ&#xff0c;本期为大家带来的是网络编程的前提概念 Socket 套接字&#xff0c;操作系统提供Socket 用于封装底层的协议细节和通信逻辑&#xff0c;使应用程序可以通过简单直观的API与网络进行交互。所以客观的…

【计算机网络】知识点总结

文章目录 1 概述1.1 计算机网络的类别1.1.1 计算机网络的定义1.1.2 计算机网络的分类1.1.2.1 不同的作用范围1.1.2.2 不同的网络使用者1.1.2.3 把用户接入因特网的网络 1.2 计算机网络的性能1.2.1 计算机网络的性能指标1.2.2 计算机网络的非性能指标 1.3 计算机网络的体系结构1…