LeetCode144. 二叉树的前序遍历

news2024/11/28 16:36:24

144. 二叉树的前序遍历

文章目录

        • [144. 二叉树的前序遍历](https://leetcode.cn/problems/binary-tree-preorder-traversal/)
          • 一、题目
          • 二、思路及代码
            • (1)递归
            • (2)迭代(两种方法)


一、题目

给你二叉树的根节点 root ,返回它节点值的 前序 遍历。

示例 1:
在这里插入图片描述

输入:root = [1,null,2,3]
输出:[1,2,3]

示例 2:

输入:root = []
输出:[]

示例 3:

输入:root = [1]
输出:[1]

示例 4:

在这里插入图片描述

输入:root = [1,2]
输出:[1,2]

示例 5:

在这里插入图片描述

输入:root = [1,null,2]
输出:[1,2]

提示:

  • 树中节点数目在范围 [0, 100]
  • -100 <= Node.val <= 100

**进阶:**递归算法很简单,你可以通过迭代算法完成吗?

二、思路及代码
(1)递归

算法思路:

这道题目要求实现二叉树的前序遍历,前序遍历的顺序是根节点、左子树、右子树。这里采用递归的方法实现前序遍历。

具体思路:

  1. 定义一个递归函数,传入根节点和结果向量
  2. 如果根节点为空,直接返回
  3. 如果根节点不为空,则先将根节点值加入结果向量
  4. 递归调用左子树,实现左子树的前序遍历
  5. 递归调用右子树,实现右子树的前序遍历
  6. 最终结果向量即为前序遍历结果

具体实现:

  1. 定义preorder递归函数,传入根节点和结果向量
  2. 判断根节点是否为空,为空直接返回
  3. 不为空则将根节点值加入结果向量vec
  4. 递归preorder左子树
  5. 递归preorder右子树
  6. 主函数中调用preorder后返回vec即为结果
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    void preorder(TreeNode*root, vector<int> &vec){
        if(root == NULL){
            return;
        }
        vec.push_back(root->val);
        preorder(root->left,vec);
        preorder(root->right,vec);
    }
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> result;
        preorder(root,result);
        return result;
    }
};

算法分析:

  • 时间复杂度:O(n),需要遍历整个二叉树的所有节点
  • 空间复杂度:最坏O(n),递归时栈的深度最多为树的高度
(2)迭代(两种方法)

版本1(更推荐)

算法思路:这道题的目标是实现二叉树的前序遍历,即遍历顺序为根节点、左子树、右子树。前序遍历可以利用栈的先入后出特性实现。

具体思路:

  1. 定义一个栈和结果数组

  2. 将根节点入栈

  3. 当栈不空时,重复以下过程:

    3.1 从栈顶取出一个节点,将该节点的值放入结果数组

    3.2 先把右子节点入栈(先右后左是为了左子节点先被取出)

    3.3 再把左子节点入栈

  4. 直到栈为空,遍历结束,返回结果数组

这种方法遵循前序遍历的访问顺序,通过栈保证每次都是取栈顶的节点,正确实现了前序遍历。

具体实现:

  1. 定义栈st和结果数组result

  2. 判断根节点是否为空,为空直接返回结果数组

  3. 不为空则将根节点root入栈

  4. 通过while循环判断栈是否为空

    4.1 从栈顶取出一个节点temp

    4.2 将temp的节点值放入结果数组

    4.3 弹出栈顶节点

    4.4 判断右子节点是否为空,不为空则入栈

    4.5 判断左子节点是否为空,不为空则入栈

  5. 遍历结束后返回结果数组

因此通过栈的先入后出实现了遍历顺序为根、左、右的前序遍历。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> result;
        stack<TreeNode*> st;
        if(root == NULL){
            return result;
        }
        st.push(root);
        while(!st.empty()){
            TreeNode *temp = st.top();
            result.push_back(temp->val);
            st.pop();
            if(temp->right != NULL){
                st.push(temp->right);
            }
            if(temp->left != NULL){
                st.push(temp->left);
            }
        }
        return result;
    }
};

算法分析:

  • 时间复杂度:O(n),其中 n 为二叉树的节点数量。需要遍历完全二叉树的所有节点。
  • 空间复杂度:O(n),其中 n 为二叉树的节点数量。栈中的元素数量不会超过树的节点数量。

版本2(思路也比较类似)

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        stack<TreeNode*> st;
        vector<int> v;
        TreeNode *p = root;
        while(p||!st.empty()){
            //当p不为空的时候,p不断向左下走
            if(p){
                v.push_back(p->val);
                st.push(p);
                p=p->left;
            }
            else{
                //当p为空的时候,寻找右兄弟,或者是叔叔结点
                p=st.top();
                st.pop();
                p=p->right;
            }
        }
        return v;
    }
};

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

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

相关文章

AlienSwap 首期 Launchpad — 偶像女团 NFT+RWA 的创新探索

NFT 是整个加密市场一致看好&#xff0c;并认为会继续爆发的领域。随着更多的 NFT 平台和 NFT 项目的推出&#xff0c;NFT 市场的格局也在不断变化。从开始的 OpenSea 占据绝对领先地位&#xff0c;到 Blur 的横空出世风头无两&#xff0c;在加密领域&#xff0c;局势更迭总是在…

【Java面试丨并发编程】线程中并发安全

一、Synchronized关键字的底层原理 1. Synchronized的作用 Synchronized【对象锁】采用互斥的方式让同一时刻至多只有一个线程能持有【对象锁】&#xff0c;其他线程再想获取这个【对象锁】时就会阻塞住 2. Monitor Synchronized【对象锁】底层是由Monitor实现&#xff0c;…

泰裤辣!这是什么操作,自动埋点,还能传参?

目录 前言 参数放在注释中 准备入口文件 编写插件 运行代码 完整代码 参数放在局部作用域中 准备源代码 编写插件 运行代码 完整代码 总结 前言 在上篇文章讲了如何通过手写babel插件自动给函数埋点之后&#xff0c;就有同学问我&#xff0c;自动插入埋点的函数怎么…

基于IMX6ULL的AP3216C的QT动态数据曲线图显示

前言&#xff1a;本文为手把手教学 LinuxQT 的典型基础项目 AP3216C 的数据折线图显示&#xff0c;项目使用正点原子的 IMX6ULL 阿尔法( Cortex-A7 系列)开发板。项目需要实现 AP3216C 在 Linux 系统下的驱动&#xff0c;使用 QT 设计 AP3216C 的数据显示页面作为项目的应用层。…

消息中间件RabbitMQ简介

1.1消息队列中间件简介 消息队列中间件是分布式系统中重要的组件&#xff0c;主要解决应用耦合&#xff0c;异步消息&#xff0c;流量削锋等问题实现高性能&#xff0c;高可用&#xff0c;可伸缩和最终一致性[架构] 使用较多的消息队列有ActiveMQ&#xff0c;RabbitMQ&#xff…

人工智能安全风险:零信任的作用

人工智能&#xff08;AI&#xff09;和机器学习技术飞速发展&#xff0c;我们所处的时代正在经历前所未有的创新。但是&#xff0c;技术飞速发展的同时也带来了各种挑战。人工智能技术越来越复杂&#xff0c;与之相关的网络安全风险也越来越棘手&#xff0c;随之产生了一个新的…

TortoiseGit 入门指南10:贮藏

有时&#xff0c;当你在项目的一部分上已经工作一段时间后&#xff0c;所有东西都进入了混乱的状态&#xff0c; 而这时你想要切换到另一个分支做一点别的事情。 问题是&#xff0c;你不想仅仅因为过会儿回到这一点而为做了一半的工作创建一次提交。 针对这个问题的答案是贮藏 …

【Linux指令集】---unzip指令(超详细)

个人主页&#xff1a;平行线也会相交 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 平行线也会相交 原创 收录于专栏【Linux专栏】&#x1f388; 本专栏旨在分享学习Linux的一点学习心得&#xff0c;欢迎大家在评论区讨论&#x1f48c; 演示环境&#xff1…

JVM系统优化实践(19):GC生产环境案例(二)

您好&#xff0c;这里是「码农镖局」CSDN博客&#xff0c;欢迎您来&#xff0c;欢迎您再来&#xff5e; 接昨天的问题继续来说&#xff0c;在高并发场景中&#xff0c;对象过多容易导致OOM。由于高并发导致Young GC存活对象过多&#xff0c;因此会有太多对象进入老年代&#xf…

关于unity Content Size Fitter 套 Content Size Fitter

首先&#xff1a;最好不要unity Content Size Fitter 套 Content Size Fitter 这样最后得到的变化可能会错误 unity也提示了&#xff0c;父物体如果有了&#xff0c;那么子物体就不要再加了。 但是你们要的需求&#xff1a; 一级父物体 ➡自适应大小➡二级父物体&#xff08…

经典目标检测R-CNN系列(2)Fast R-CNN

经典目标检测R-CNN系列(2)Fast R-CNN Fast R-CNN是作者Ross Girshick继R-CNN后的又一力作。 同样使用VGG16作为网络的backbone&#xff0c;与R-CNN相比训练时间快9倍&#xff0c;测试推理时间快213倍&#xff0c;准确率从62%提升至66%(Pascal VOC数据集上)。 1 Fast R-CNN的…

Java List 与数组互转

前言 略 数组转 List 方法1 Employee[] array new Employee[]{emp1, emp2, emp3}; List<Employee> list Arrays.asList(array);Arrays.asList 返回的是固定长度的数组&#xff0c;扩大或缩小列表的操作将返回UnsupportedOperationException。 数组转 List 方法2 E…

【C++STL】“vector“容器的模拟实现

vector的模拟实现 模拟实现成员变量构造函数无参构造函数初始化n个val的构造函数迭代器区间构造函数 拷贝构造析构函数begin&#xff08;&#xff09;end&#xff08;&#xff09;swap&#xff08;&#xff09;reserve()resize()capacity()size()重载[]运算符重载赋值运算符ins…

自学网络安全(黑客)为什么火了?

网安专业从始至终都是需要学习的&#xff0c;大学是无法培养出合格的网安人才的。这就是为啥每年网安专业毕业生并不少&#xff0c;而真正从事网安岗位的人&#xff0c;寥寥无几的根本原因。 如果将来打算从事网安岗位&#xff0c;那么不断学习是你唯一的途径。 网络安全为什…

应对 618、双十一等大促期间的高负载,API 性能测试应该怎么做?负载测试、基线测试、冒烟测试、浸泡测试、峰值测试和尖峰测试详解

随着应用程序和服务交付速度的不断提高&#xff0c;在按时交付应用程序的竞赛中&#xff0c;性能测试往往会退居其次。但是&#xff0c;在节假日期间&#xff0c;购物额都会大幅增长。在这种一年中的成败时刻&#xff0c;公司是无法接受他们的应用程序在高负载下变得不可靠的。…

第四章 云原生架构之Kubernetes基础知识

1、K8S整体架构 1.1、概述 ​ Kubernetes是一个可移植、可扩展的开源平台&#xff0c;用于管理容器化的工作负载和服务&#xff0c;简称 K8S。K8S的本质是一组服务器集群&#xff0c;可以在对应服务器集群的每个节点上运行程序&#xff0c;来对节点中的容器进行管理。类似Mas…

Pytest+Jenkins+Allure的接口自动化测试

目录 生成Allure 两种形式 一 项目内直接生成不依赖Jenkins 1.先安装好allure 将allure\bin配置到环境变量中 cmd 命令行输入&#xff1a;allure 校验是否安装成功 2. 将json文件生成html文件 执行 allure generate report/ -o report/html其中的report/ 为生成的json路径&a…

OCPM和CPM有什么区别?

CPM和OCPM这两种收费模式的对比 Cpm&#xff1a;表示千次展示费用&#xff0c;是数据指标&#xff0c;也是一种出价方式。代表展现一千次的消费&#xff0c;也就是你展现1000次要给媒体多少钱 例如某企业广告曝光量是50万&#xff0c;总广告价格为10000元&#xff0c;那么千人…

matplotlib 笔记:marker 款式

1 ec 边缘颜色 marker 边缘的颜色 import numpy as np import matplotlib.pyplot as pltxnp.linspace(0,10) ynp.sin(x)1.5 plt.figure(figsize(10,10)) plt.scatter(x,y,ecC9) plt.show() 2 fc 填充颜色 face color 填充颜色 3 lw 边缘宽度 4 s 点的大小 5 marker 点款式 i…

设计模式 ~ 工厂模式

工厂模式 工厂模式是一种设计模式&#xff0c;指在通过使用工厂函数或构造函数来创建对象&#xff1b; 它提供了一种灵活的方式来创建对象实例&#xff0c;而无需直接调用构造函数或使用new关键字&#xff1b; 可以分类&#xff0c;解耦&#xff1b; 可以扩展多个类&#xff0…