LeetCode 94. 二叉树的中序遍历

94. 二叉树的中序遍历

给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。

示例 1:

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

输出:[1,3,2]

示例 2:

输入:root = []

输出:[]

示例 3:

输入:root = [1]

输出:[1]

提示:

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

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

解法思路:

1、递归(Recursion)

2、迭代维护栈(Iterator)

3、Morris 中序遍历(了解一下)

Morris 遍历算法是另一种遍历二叉树的方法,它能将非递归的中序遍历空间复杂度降为 O(1)

Morris 遍历算法步骤(假设当前遍历到的节点为 x):

  • 若 x 无左孩子
    • x 加入结果
    • x = x.right
  • 若 x 有左孩子,找 x 左子树的最右边的节点 predecessor
    • predecessor 右孩子为空,右孩子指向x,x = x.left
    • predecessor 右孩子不为空,x 加入结果,x = x.right
  • 重复上述步骤,直到访问完整棵树

法一:

/**
 * 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 {
    public List<Integer> inorderTraversal(TreeNode root) {
        // Recursion
        // Time: O(n)
        // Space: O(n)
        List<Integer> res = new ArrayList<>();
        inorder(root, res);
        return res;
    }

    private void inorder(TreeNode root, List<Integer> res) {
        if (root == null) return;
        inorder(root.left, res);
        res.add(root.val);
        inorder(root.right, res);
    }
}

法二:

/**
 * 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 {
    public List<Integer> inorderTraversal(TreeNode root) {
        // Iterator
        // Time: O(n)
        // Space: O(n)
        List<Integer> res = new ArrayList<>();
        Deque<TreeNode> stack = new ArrayDeque<>();
        while (root != null || !stack.isEmpty()) {
            while (root != null) {
                stack.addLast(root);
                root = root.left;
            }
            root = stack.removeLast();
            res.add(root.val);
            root = root.right;
        }
        return res;
    }
}

法三: 

/**
 * 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 {
    public List<Integer> inorderTraversal(TreeNode root) {
        // Morris
        // Time: O(n)
        // Space: O(1)
        // Morris 遍历算法步骤(假设当前遍历到的节点为 x):
        // 若 x 无左孩子
        //      x 加入结果
        //      x = x.right
        // 若 x 有左孩子,找 x 左子树的最右边的节点 predecessor
        //      predecessor 右孩子为空,右孩子指向x,x = x.left
        //      predecessor 右孩子不为空,x 加入结果,x = x.right
        // 重复上述步骤,直到访问完整棵树
        List<Integer> res = new ArrayList<>();
        TreeNode predecessor = null;
        while (root != null) {
            if (root.left != null) {
                // predecessor 节点就是当前 root 节点向左走一步,然后一直向右走至无法走为止
                predecessor = root.left;
                while (predecessor.right != null && predecessor.right != root) {
                    predecessor = predecessor.right;
                }
                // 让 predecessor 的右指针指向 root,继续遍历左子树
                if (predecessor.right == null) {
                    predecessor.right = root;
                    root = root.left;
                } else { // 说明左子树已经访问完了,需要断开链接
                    res.add(root.val);
                    predecessor.right = null;
                    root = root.right;
                }
            } else {
                res.add(root.val);
                root = root.right;
            }
        }
        return res;
    }
}

 

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

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

相关文章

cctalk录屏去水印翻录过检测教程

最近在上cctalk的网课时候&#xff0c;遇到了这种情况&#xff0c;无法打开录屏工具&#xff0c;打开了录屏软件会被播放器检测&#xff0c;无法正常播放网课视频&#xff0c;可以用这个工具&#xff0c;就可以随便录了&#xff0c;而且可以去用户名水印。 使用方法也很简单&a…

springboot+java+bootstrap商场摊位商铺租赁管理系统

商铺租赁管理系统分为管理员&#xff0c;房东&#xff0c;用户三种角色。 &#xff08;1&#xff09;管理员功能&#xff1a;管理员管理房东&#xff0c;管理公告&#xff0c;管理商铺出租&#xff0c;租赁合同等信息。 &#xff08;2&#xff09;房东功能&#xff1a;房东审核…

参数小,性能强!开源多模态模型—TinyGPT-V

安徽工程大学、南洋理工大学和理海大学的研究人员开源了多模态大模型——TinyGPT-V。 TinyGPT-V以微软开源的Phi-2作为基础大语言模型&#xff0c;同时使用了视觉模型EVA实现多模态能力。尽管TinyGPT-V只有28亿参数&#xff0c;但其性能可以媲美上百亿参数的模型。 此外&…

0基础学习VR全景平台篇第136篇:720VR全景,认识无人机

上课&#xff01;全体起立~ 大家好&#xff0c;欢迎观看蛙色官方系列全景摄影课程&#xff01; 无人驾驶飞行器&#xff0c;简称“无人机”&#xff0c;英文缩写为“UAV”。是利用无线电控制设备和自备程序控制操纵的不载人飞机。 &#xff08;一&#xff09;无人机介绍 较…

vue element plus 安装

环境支持# Element Plus 可以在支持 ES2018 和 ResizeObserver 的浏览器上运行。 如果您确实需要支持旧版本的浏览器&#xff0c;请自行添加 Babel 和相应的 Polyfill 。 由于 Vue 3 不再支持 IE11&#xff0c;Element Plus 也不再支持 IE 浏览器。 Edge ≥ 79Firefox ≥ 78C…

信号-进程间通信

信号 1. 信号概述 在 Linux 操作系统中&#xff0c;信号是一种进程间通信的机制&#xff0c;用于通知进程发生了某个事件。信号可以由内核、其他进程&#xff0c;或者进程自身发送。每个信号都对应一个特定的事件或异常&#xff0c;例如进程终止、CtrlC 中断等。 本质上是一…

使用AUTOSAR来开发汽车基础软件的优点

1、高质量。以前我们采用手写代码的方式&#xff0c;是几个工程师在战斗。现在我们采用平台&#xff0c;BSW代码都是供应商提供的&#xff0c;我们相当于后面还有一个团队陪着我们在战斗。 2、低成本。大家都说采用AUTOSAR平台好贵&#xff0c;但是从长远来看是值得的&#xff…

利用虾皮Shopee API (shopee.item_get)提升电商平台用户转化率与客单价

在当今的电商环境中&#xff0c;用户转化率和客单价是衡量电商平台成功与否的关键指标。虾皮Shopee作为一个领先的电商平台&#xff0c;提供了丰富的API服务&#xff0c;其中shopee.item_get接口允许商家根据商品ID获取详细的商品信息。通过合理利用这一API&#xff0c;商家可以…

glusterFS

一. 概念 1. 介绍 gluster是一个横向扩展的分布式文件系统&#xff0c;可将来自多个服务器的磁盘存储资源整合到一个全局名称空间中&#xff0c;可以根据存储消耗需求快速调配额外的存储。它将自动故障转移作为主要功能. 分布式存储系统.集群式NAS存储.无集中式元数据服务,采…

笔记本摄像头模拟监控推送RTSP流

使用笔记本摄像头模拟监控推送RTSP流 一、基础安装软件准备 本文使用软件下载链接:下载地址 FFmpeg软件: Download ffmpeg 选择Windows builds by BtbN 一个完整的跨平台解决方案&#xff0c;用于录制、转换和流式传输音频和视频。 EasyDarwin软件&#xff1a;Download Easy…

激活函数整理

sigmoid函数 import torch from d2l import torch as d2l %matplotlib inline ​ xtorch.arange(-10,10,0.1,requires_gradTrue) sigmoidtorch.nn.Sigmoid() ysigmoid(x) ​ d2l.plot(x.detach(),y.detach(),x,sigmoid(x),figsize(5,2.5)) sigmoid函数连续、光滑、单调递增&am…

java数据结构与算法刷题-----LeetCode343. 整数拆分(TODO)

java数据结构与算法刷题目录&#xff08;剑指Offer、LeetCode、ACM&#xff09;-----主目录-----持续更新(进不去说明我没写完)&#xff1a;https://blog.csdn.net/grd_java/article/details/123063846 很多人觉得动态规划很难&#xff0c;但它就是固定套路而已。其实动态规划只…

C++力扣题目226--翻转二叉树

给你一棵二叉树的根节点 root &#xff0c;翻转这棵二叉树&#xff0c;并返回其根节点。 示例 1&#xff1a; 输入&#xff1a;root [4,2,7,1,3,6,9] 输出&#xff1a;[4,7,2,9,6,3,1]示例 2&#xff1a; 输入&#xff1a;root [2,1,3] 输出&#xff1a;[2,3,1]示例 3&#x…

【算法与数据结构】746、LeetCode使用最小花费爬楼梯

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析&#xff1a;本题可以从0阶或者1阶台阶开始&#xff0c;每次爬楼梯所需的花费是之前的花费dp[i]从本层向上爬所需的…

入门实战丨Python小游戏经典案例

文章目录 写在前面判断与循环小游戏猜数游戏龙的世界 写在后面 写在前面 本期内容&#xff1a;两个个简单的Python小游戏入门案例。 实验需求&#xff1a;python 实验目标&#xff1a;掌握基本的判断与循环语句。 判断与循环 判断与循环是编程中非常重要的两个概念&#x…

机器学习顶会ICML 2024今日开放投稿,CCF A类,中稿率27.94%(附ICML23杰出论文+18篇高分论文)

ICML 2024今天开放投稿了&#xff01;距离截稿还有24天&#xff0c;想冲ICML的同学速度&#xff01; ICML 全称 International Conference on Machine Learning&#xff0c;由国际机器学习学会&#xff08;IMLS&#xff09;举办&#xff0c;与NIPS一同被认为是人工智能、机器学…

面试宝典进阶之redis缓存面试题

R1、【初级】Redis常用的数据类型有哪些&#xff1f; &#xff08;1&#xff09;String&#xff08;字符串&#xff09; &#xff08;2&#xff09;Hash&#xff08;哈希&#xff09; &#xff08;3&#xff09;List&#xff08;列表&#xff09; &#xff08;4&#xff09;Se…

程序员面试技巧:成为HR心动的程序猿

文章目录 程序员必备的面试技巧导语一、准备充分二、突出亮点三、展示解决问题的能力四、良好的沟通能力五、积极展示学习态度示例结语&#x1f636; 写在结尾 程序员必备的面试技巧 “程序员必备的面试技巧&#xff0c;就像是编写一段完美的代码一样重要。在面试战场上&#…

vue3 +TS 安装使用pinia状态管理

目录 一.安装 1.下载安装依赖 2.创建src/stores/index.ts文件 3.创建src/stores/states.ts文件 4.创建src/stores/interface/index.ts文件 5.修改main.ts 6.目录结构如下 7.测试使用 8.去到首页点击按钮&#xff0c;打开控制台查看 一.安装 1.下载安装依赖 npm insta…

人类认知中的等价机理与机器智能中等价机理

人类认知中的等价机理是指人们在认知过程中&#xff0c;通过将不同的概念、事物或情境进行等价替代&#xff0c;从而实现思维的连贯和理解的补充。例如&#xff0c;当人们看到一个陌生的动物时&#xff0c;可以将它与已知的动物进行等价对应&#xff0c;从而理解其特征和行为。…