多叉树题目:N 叉树的后序遍历

文章目录

  • 题目
    • 标题和出处
    • 难度
    • 题目描述
      • 要求
      • 示例
      • 数据范围
      • 进阶
  • 解法一
    • 思路和算法
    • 代码
    • 复杂度分析
  • 解法二
    • 思路和算法
    • 代码
    • 复杂度分析
  • 解法三
    • 思路和算法
    • 代码
    • 复杂度分析

题目

标题和出处

标题:N 叉树的后序遍历

出处:590. N 叉树的后序遍历

难度

3 级

题目描述

要求

给定一个 N 叉树的根结点 root \texttt{root} root,返回其结点值的后序遍历。

N 叉树在输入中按层序遍历序列化表示,每组子结点由空值 null \texttt{null} null 分隔(请参见示例)。

示例

示例 1:

示例 1

输入: root   =   [1,null,3,2,4,null,5,6] \texttt{root = [1,null,3,2,4,null,5,6]} root = [1,null,3,2,4,null,5,6]
输出: [5,6,3,2,4,1] \texttt{[5,6,3,2,4,1]} [5,6,3,2,4,1]

示例 2:

示例 2

输入: root   =   [1,null,2,3,4,5,null,null,6,7,null,8,null,9,10,null,null,11,null,12,null,13,null,null,14] \texttt{root = [1,null,2,3,4,5,null,null,6,7,null,8,null,9,10,null,null,11,null,12,null,13,null,null,14]} root = [1,null,2,3,4,5,null,null,6,7,null,8,null,9,10,null,null,11,null,12,null,13,null,null,14]
输出: [2,6,14,11,7,3,12,8,4,13,9,10,5,1] \texttt{[2,6,14,11,7,3,12,8,4,13,9,10,5,1]} [2,6,14,11,7,3,12,8,4,13,9,10,5,1]

数据范围

  • 树中结点数目在范围 [0,   10 4 ] \texttt{[0, 10}^\texttt{4}\texttt{]} [0, 104]
  • 0 ≤ Node.val ≤ 10 4 \texttt{0} \le \texttt{Node.val} \le \texttt{10}^\texttt{4} 0Node.val104
  • N 叉树的高度小于或等于 1000 \texttt{1000} 1000

进阶

递归解法很简单,你可以使用迭代解法完成吗?

解法一

思路和算法

N 叉树的后序遍历的方法为:按照从左到右的顺序依次遍历每个子树,最后遍历根结点,对于每个子树使用同样的方法遍历。由于遍历过程具有递归的性质,因此可以使用递归的方法实现 N 叉树的后序遍历。

递归的终止条件是当前结点为空。对于非终止条件,递归的做法如下。

  1. 按照从左到右的顺序,依次对当前结点的每个子树调用递归。

  2. 将当前结点的结点值加入后序遍历序列。

遍历结束之后即可得到后序遍历序列。

代码

class Solution {
    List<Integer> traversal = new ArrayList<Integer>();

    public List<Integer> postorder(Node root) {
        postorderVisit(root);
        return traversal;
    }

    public void postorderVisit(Node node) {
        if (node == null) {
            return;
        }
        List<Node> children = node.children;
        for (Node child : children) {
            postorderVisit(child);
        }
        traversal.add(node.val);
    }
}

复杂度分析

  • 时间复杂度: O ( m ) O(m) O(m),其中 m m m 是 N 叉树的结点数。每个结点都被访问一次。

  • 空间复杂度: O ( m ) O(m) O(m),其中 m m m 是 N 叉树的结点数。空间复杂度主要是递归调用的栈空间,取决于 N 叉树的高度,最坏情况下 N 叉树的高度是 O ( m ) O(m) O(m)

解法二

思路和算法

使用迭代的方法实现 N 叉树的后序遍历,则需要使用栈存储结点。

由于后序遍历的过程中,对于同一个结点的子树的访问顺序是从左到右,因此当访问一个结点之后,将该结点的所有子结点按照从右到左的顺序依次入栈,则利用栈的后进先出的特点,子结点的出栈顺序为从左到右的顺序,和后序遍历的顺序相同。

由于后序遍历对于每个子树都是最后访问根结点,因此需要使用哈希集合存储已经访问过的结点,才能确保不会重复访问同一个结点。

当树为空时,后序遍历列表为空。当树不为空时,首先将根结点入栈,然后按照如下操作执行后序遍历。

  1. 获得栈顶结点和栈顶结点的子结点。

  2. 如果栈顶结点已经在哈希集合中或者栈顶结点没有子结点,则将栈顶结点出栈,将出栈结点的结点值加入后序遍历序列;如果栈顶结点不在哈希集合中且栈顶结点有子结点,则将栈顶结点的所有子结点按照从右到左的顺序依次入栈。

  3. 重复上述操作,直到栈为空时,后序遍历结束。

代码

class Solution {
    public List<Integer> postorder(Node root) {
        List<Integer> traversal = new ArrayList<Integer>();
        if (root == null) {
            return traversal;
        }
        Set<Node> set = new HashSet<Node>();
        Deque<Node> stack = new ArrayDeque<Node>();
        stack.push(root);
        while (!stack.isEmpty()) {
            Node node = stack.peek();
            List<Node> children = node.children;
            if (set.contains(node) || children.isEmpty()) {
                stack.pop();
                traversal.add(node.val);
            } else {
                set.add(node);
                for (int i = children.size() - 1; i >= 0; i--) {
                    stack.push(children.get(i));
                }
            }
        }
        return traversal;
    }
}

复杂度分析

  • 时间复杂度: O ( m ) O(m) O(m),其中 m m m 是 N 叉树的结点数。每个结点都被访问一次。

  • 空间复杂度: O ( m ) O(m) O(m),其中 m m m 是 N 叉树的结点数。空间复杂度主要是哈希集合和栈空间,哈希集合和栈内元素个数不超过 m m m

解法三

思路和算法

另一种使用迭代实现 N 叉树的后序遍历的方法是使用哈希表存储每个结点的已访问的最后一个子结点下标(以下简称「子结点下标」),而不是将子结点按照从右到左的顺序入栈,同样需要使用栈存储结点。

从根结点开始遍历,遍历的终止条件是栈为空且当前结点为空。遍历的做法如下。

  1. 如果当前结点不为空,则将当前结点入栈。如果当前结点不是叶结点,则将当前结点的子结点下标设为 0 0 0,将当前结点移动到其子结点中的最左侧的子结点,重复上述操作。如果当前结点是叶结点,则在执行上述操作之后将当前结点设为空。

  2. 将栈顶结点的子结点下标加 1 1 1 记为新下标,则新下标为下一个待访问的子结点下标。如果新下标在子结点下标范围内则用新下标更新栈顶结点的子结点下标,将当前结点设为下一个待访问的结点;如果新下标不在子结点下标范围内则将当前结点的结点值加入后序遍历序列,将栈顶结点出栈,将当前结点设为空。

  3. 重复上述操作,直到达到遍历的终止条件。

代码

class Solution {
    public List<Integer> postorder(Node root) {
        List<Integer> traversal = new ArrayList<Integer>();
        if (root == null) {
            return traversal;
        }
        Map<Node, Integer> map = new HashMap<Node, Integer>();
        Deque<Node> stack = new ArrayDeque<Node>();
        Node node = root;
        while (!stack.isEmpty() || node != null) {
            while (node != null) {
                stack.push(node);
                List<Node> children = node.children;
                if (!children.isEmpty()) {
                    map.put(node, 0);
                    node = children.get(0);
                } else {
                    node = null;
                }
            }
            node = stack.peek();
            int index = map.getOrDefault(node, -1) + 1;
            List<Node> children = node.children;
            if (index < children.size()) {
                map.put(node, index);
                node = children.get(index);
            } else {
                traversal.add(node.val);
                stack.pop();
                map.remove(node);
                node = null;
            }
        }
        return traversal;
    }
}

复杂度分析

  • 时间复杂度: O ( m ) O(m) O(m),其中 m m m 是 N 叉树的结点数。每个结点都被访问一次。

  • 空间复杂度: O ( m ) O(m) O(m),其中 m m m 是 N 叉树的结点数。空间复杂度主要是哈希表和栈空间,哈希表和栈内元素个数都不超过 m m m

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

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

相关文章

Android笔记(三十):PorterDuffXfermode实现旋转进度View

背景 核心原理是使用PorterDuffXfermode Path来绘制进度&#xff0c;并实现圆角 效果图 Android笔记(三十)效果演示 进度条绘制步骤 将ImageView矩形七个点的坐标存储起来&#xff08;configNodes&#xff09; 他们对应着7个不同的刻度&#xff0c;每个刻度的值 i * &#…

Unity | 射线检测及EventSystem总结

目录 一、知识概述 1.Input.mousePosition 2.Camera.ScreenToWorldPoint 3.Camera.ScreenPointToRay 4.Physics2D.Raycast 二、射线相关 1.3D&#xff08;包括UI&#xff09;、射线与ScreenPointToRay 2.3D&#xff08;包括UI&#xff09;、射线与ScreenToWorldPoint …

计算机基础,挑战全网最全解析

1.什么是计算机&#xff1f; 2.冯诺依曼结构 3.进制 4.摩尔斯码和布莱叶盲文 摩尔斯码 布莱叶盲文

如何使用群晖WebDAV实现固定公网地址同步Zotero文献管理器

文章目录 前言1. Docker 部署 Trfɪk2. 本地访问traefik测试3. Linux 安装cpolar4. 配置Traefik公网访问地址5. 公网远程访问Traefik6. 固定Traefik公网地址 前言 Trfɪk 是一个云原生的新型的 HTTP 反向代理、负载均衡软件&#xff0c;能轻易的部署微服务。它支持多种后端 (D…

蓝桥杯嵌入式学习笔记(6):IIC程序设计

目录 前言 1. IIC基本原理 2. 电路原理 3. 代码编程 3.1 预备工作 3.2 AT24C02写读功能编写 3.2.1 AT24C02写操作实现 3.2.2 AT24C02读操作实现 3.3 MCP4017写读功能编写 3.3.1 MCP4017写操作实现 3.3.2 MCP4017读操作实现 3.4 main.c编写 3.4.1 头文件引用 3.4.…

基于javaweb(springboot+mybatis)网上酒类商城项目设计和实现以及文档报告

基于javaweb(springbootmybatis)网上酒类商城项目设计和实现以及文档报告 博主介绍&#xff1a;多年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞…

Redis数据类型介绍和使用

数据类型 String&#xff08;字符串&#xff09;&#xff1a;最基本的数据类型&#xff0c;可以存储任何类型的数据&#xff0c;如文本、数字等。Hash&#xff08;哈希&#xff09;&#xff1a;用于存储字段-值对的散列集合&#xff0c;适用于存储对象。List&#xff08;列表&…

鱼哥赠书活动第14期:看完这本《数字化运维》掌握数字化运维方法,构建数字化运维体系

鱼哥赠书活动第14期&#xff1a;看完这本《数字化运维》掌握数字化运维方法&#xff0c;构建数字化运维体系 主要内容&#xff1a;读者对象&#xff1a;赠书抽奖规则:往期赠书福利&#xff1a; 数字化转型已经成为大势所趋&#xff0c;各行各业正朝着数字化方向转型&#xff0c…

如何在群晖NAS搭建bitwarden密码管理软件并实现无公网IP远程访问

前言 作者简介&#xff1a; 懒大王敲代码&#xff0c;计算机专业应届生 今天给大家聊聊如何在群晖NAS搭建bitwarden密码管理软件并实现无公网IP远程访问&#xff0c;希望大家能觉得实用&#xff01; 欢迎大家点赞 &#x1f44d; 收藏 ⭐ 加关注哦&#xff01;&#x1f496;&am…

【数据结构】链表习题之环形链表的约瑟夫问题

&#x1f451;个人主页&#xff1a;啊Q闻 &#x1f387;收录专栏&#xff1a;《数据结构》 &#x1f389;道阻且长&#xff0c;行则将至 前言 今天这道题目时牛客上的题目&#xff0c;名为环形链表的约瑟夫问题&#xff0c;很有趣的的一道题目 环形链表的约瑟…

申请免费域名证书

目录 背景&#xff1a; 域名证书是什么&#xff1a; 域名证书有哪些&#xff1a; 部署域名证书有什么用&#xff1a; 免费的域名证书在哪里申请&#xff1a; 背景&#xff1a; 域名是一个IP地址上的“面具” 。一个域名的目的是便于记忆和沟通的一组服务器的地址(网站&…

OpenHarmony开发知识点记录之ABI

OpenHarmony系统支持丰富的设备形态&#xff0c;支持多种架构指令集&#xff0c;支持多种操作系统内核&#xff1b;为了应用在各种OpenHarmony设备上的兼容性&#xff0c;本文定义了"OHOS" ABI&#xff08;Application Binary Interface&#xff09;的基础标准&#…

路由协议RIP(悄悄话)

实验要求&#xff1a;总部和两个分支&#xff0c;拓扑如下图&#xff0c;利用rip路由协议使得各个pc设备可以通信 RIP理解&#xff1a;相邻路由定期交换内部路由协议&#xff0c;最后达到稳定状态&#xff0c;如果发生网络发生变化&#xff0c;重复交换路由步骤直到稳定状态&a…

LinkedIn 互联网架构扩展简史

LinkedIn成立于 2003 年&#xff0c;其目标是连接到您的网络以获得更好的工作机会。第一周只有 2,700 名会员。时间快进了很多年&#xff0c;LinkedIn 的产品组合、会员基础和服务器负载都取得了巨大的增长。 如今&#xff0c;LinkedIn 在全球运营&#xff0c;拥有超过 3.5 亿会…

研华工控机610L学习笔记2:visualstudio与第一个C#程序

今日继续学习工控机 C# 编程相关知识&#xff1a; 这篇结束后我将先进行一段时间的C#的学习研究&#xff0c;并写一些C#的笔记 后续再更新工控机编程设计相关 目录 1、安装visualstudio&#xff1a; 2、创建第一个C#程序&#xff1a; 3、寻找C#解决方案源文件&#xff1a; …

梦幻西游端游全新升级瀚海游戏玩法 一单35 小白一手机没脑子实际操作 日入3000

大家好&#xff0c;很多人都听过抖音游戏外国投资者方案&#xff0c;但是大部分人做视频&#xff0c;收益都非常低。 今天给带来的项目是“梦幻西游端游全新升级瀚海游戏玩法&#xff0c;一单35&#xff0c;轻松日入3000”&#xff0c;这个项目不用去被割韭菜&#xff0c;我自…

IDEA | 资源文件中文乱码问题解决

问题 IDEA打开资源文件&#xff0c;显示乱码问题。 解决方案 1、电脑是mac&#xff0c;点击IDEA->【Preferences】->【Editor】->【File Encodings】 2、选择【Properties Files】中的UTF-8&#xff0c;并勾选Transparent native-to-ascii conversion。 3、最后点击…

P5727 【深基5.例3】冰雹猜想

【深基5.例3】冰雹猜想 - 洛谷https://www.luogu.com.cn/problem/P5727这种方法比较繁琐&#xff0c;预先定义固定的数组长度&#xff0c;很局限&#xff1a; public class Main {public static void main(String[] args) {Scanner sc new Scanner(System.in);int n sc.next…

图神经网络和图卷积网络

图神经网络要点 1. GNNs adopt a “graph-in, graph-out” architecture meaning that these model types accept a graph as input, with information loaded into its nodes, edges and global-context, and progressively transform these embeddings, without changing th…

黑马头条知识点总结

黑马头条知识点总结 文章目录 黑马头条知识点总结前言一、使用的所有技术栈二、初始化项目 2.1加密盐登录2.2网关2.3配置nginx三。文章通过freemarker生成html文件存入minio中四。内容安全阿里云接口5.使用延迟任务发布审核文章 4.9.3)redis分布式锁在工具类CacheService中添加…