46 二叉树展开为链表

news2024/11/25 14:58:54

二叉树展开为链表

    • 理解题意:前序遍历的N种写法
    • 题解1 前序遍历
    • 题解2 反前序遍历(代码简洁)
    • 题解3 类似旋转的方法
    • 题解4 迭代
    • 题解5 同时遍历+改左右子树

给你二叉树的根结点 root ,请你将它展开为一个单链表:

展开后的单链表应该同样使用 TreeNode ,其中 right 子指针指向链表中下一个结点,而左子指针始终为 null
展开后的单链表应该与二叉树先序遍历顺序相同。

在这里插入图片描述
提示:

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

理解题意:前序遍历的N种写法

题解1 前序遍历

/**
 * 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 {
    vector<TreeNode*> arr;
public:
    void dfs(TreeNode* root){
        if(! root) return;
        arr.push_back(root);
        dfs(root->left);
        dfs(root->right);
    } 
    void flatten(TreeNode* root) {
        if(! root) return;
        dfs(root);
        for(int i = 1; i < arr.size(); i++){
            root->right = arr[i];
            root->left = nullptr;
            root = root->right;
        }
    }
};

在这里插入图片描述

题解2 反前序遍历(代码简洁)

class Solution {
    TreeNode* preNode;
public:
    void flatten(TreeNode* root) {
        if (! root) return;
        // right先压栈(后面弹)
        flatten(root->right);
        flatten(root->left);
        // 第一次执行 root是前序遍历的最后访问的结点
        root->left = NULL;
        root->right = preNode;
        preNode = root;
    }
};

在这里插入图片描述

题解3 类似旋转的方法

class Solution {
    TreeNode* preNode;
public:
    void flatten(TreeNode* root) {
        TreeNode *curr = root;
        while (curr != nullptr) {
            if (curr->left != nullptr) {
                auto next = curr->left;
                auto predecessor = next;
                while (predecessor->right != nullptr) {
                    predecessor = predecessor->right;
                }
                predecessor->right = curr->right;
                curr->left = nullptr;
                curr->right = next;
            }
            curr = curr->right;
        }
    }
};

在这里插入图片描述

题解4 迭代

class Solution {
    TreeNode* preNode;
public:
    void flatten(TreeNode* root) {
        auto v = vector<TreeNode*>();
        auto stk = stack<TreeNode*>();
        TreeNode *node = root;
        while (node != nullptr || !stk.empty()) {
            while (node != nullptr) {
            // 前序遍历: 动作放在最前面
                v.push_back(node);
                stk.push(node);
                node = node->left;
            }
            node = stk.top(); 
            stk.pop();
            node = node->right;
        }
        int size = v.size();
        for (int i = 1; i < size; i++) {
            auto prev = v.at(i - 1), curr = v.at(i);
            prev->left = nullptr;
            prev->right = curr;
        }
    }
};

在这里插入图片描述

题解5 同时遍历+改左右子树

void flatten(TreeNode* root) {
        if (root == nullptr) {
            return;
        }
        auto stk = stack<TreeNode*>();
        stk.push(root);
        TreeNode *prev = nullptr;
        while (!stk.empty()) {
            TreeNode *curr = stk.top(); 
            stk.pop();
            if (prev != nullptr) {
                prev->left = nullptr;
                prev->right = curr;
            }
            TreeNode *left = curr->left, *right = curr->right;
            // 防止脏数据,原数据先放进stack里
            if (right != nullptr) {
                stk.push(right);
            }
            if (left != nullptr) {
                stk.push(left);
            }
            //迭代
            prev = curr;
        }
    }

在这里插入图片描述

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

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

相关文章

判断当日是否为当月第一个交易日——时间相关函数3

本文介绍的函数用于判断当前交易日是否为当月的第一个交易日。 在某些策略中&#xff0c;可能会在每月的第一个交易日进行调仓换股。这时&#xff0c;就可以使用本文介绍的函数判断当日是否为当月的第一个交易日。 源码 def is_first_trading_day_of_month():""&q…

老虎证券当前股价已严重背离基本面,下半年收入将下滑

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 老虎证券近期股价表现优异 在过去的一个月里&#xff0c;老虎证券(TIGR)的股价表现令人惊叹&#xff0c;其估值也大幅上升。 在过去一个月里&#xff0c;老虎证券的股价上涨了45.0%&#xff0c;而同期以标普500指数为代表的…

VMWare Vcenter Server克隆虚拟机所用端口

Vcenter server 管理ESXi主机时需要用到的端口主要有443和902端口&#xff0c;很多文档都要求双向通信&#xff0c;实际上可以通过查看ESXI主机的防火墙配置了解相关端口。 1. ESXi 对外提供的端口 主要是有 vsphere Web client 服务的入站端口&#xff1a; TCP 902 和 TCP 4…

Javascript之Object、Array

Object.keys 对象的键转化为数组 Object.values 对象的属性值转化为数组 Object.assign 对象的合并 Array.from() 伪数组对象的属性值转化为数组。类似Object.values Array. reduce(function(prev, currentValue, currentIndex, arr), initialValue) 数组多个元素的值合并减为单…

平板第三方电容笔怎么样?便宜的ipad触控笔推荐

苹果原装的电容笔与国产的平替电容笔最大的区别在于&#xff0c;平替电容笔只有一个斜面压力感应&#xff0c;而苹果电容笔既有斜面压力感应&#xff0c;又有重力压力感应。但是&#xff0c;如果你不经常使用它来进行绘画的话&#xff0c;你也不必买选择这款苹果电容笔&#xf…

Acwing.800 数组元素的目标和

题目 给定两个升序排序的有序数组A和B&#xff0c;以及一个目标值x。数组下标从0开始。请你求出满足A[i]Bi]x的数对(i, j)。 数据保证有唯一解。 输入格式 第一行包含三个整数n&#xff0c;m&#xff0c;x&#xff0c;分别表示A的长度&#xff0c;B的长度以及目标值x。第二行…

awk 命令

语法格式&#xff1a; awk [选项参数] ‘/pattern1/{action1} /pattern2/{action2}...’ filename pattern&#xff1a;表示 awk 在数据中查找的内容&#xff0c;就是匹配模式 action&#xff1a;在找到匹配内容时所执行的一系列命令awk常见参数选项&#xff1a; awk常见内置变…

❋JQuery的快速入门2 jq鼠标滚轮

onmousewheelscript当鼠标滚轮正在被滚动时运行的脚本。 主要是利用top与left进行上下移动和左右移动 【使用获取的角度正值还是负值&#xff0c;判断是向上还是上下滚动】 $(element).on("mousewheel", function(event){var de event.originalEvent.deltaY; //需要…

机器学习之旅-从Python 开始

你想知道如何开始机器学习吗&#xff1f;在这篇文章中&#xff0c;我将简要概括一下使用 Python 来开始机器学习的一些步骤。Python 是一门流行的开源程序设计语言&#xff0c;也是在人工智能及其它相关科学领域中最常用的语言之一。机器学习简称 ML&#xff0c;是人工智能的一…

Swift SwiftUI CoreData 过滤数据 2

预览 Code import SwiftUI import CoreDatastruct HomeSearchView: View {Environment(\.dismiss) var dismissState private var search_value ""FetchRequest(entity: Bill.entity(),sortDescriptors: [NSSortDescriptor(keyPath: \Bill.c_at, ascending: false)…

redis(4)-hiredis-API函数的调用

1.下载安装编译 windowslinuxredis下载 redis-plus-plus-master.zip文件的下载 http://download.redis.io/releases/redis-7.2.0.tar.gz tar -zxvf redis-7.2.0.tar.gz //-z:gzip属性 ;-x&#xff1a;解压&#xff1b;-v:显示&#xff1b;-f:文件 make make install //m…

华为2023鲲鹏应用创新大赛,实在智能“信创RPA”再获殊荣

近期&#xff0c;面向全球开发者的顶级赛事鲲鹏应用创新大赛2023成功举办&#xff0c;旨在鼓励广大开发者基于鲲鹏全栈根技术&#xff0c;围绕产业真实难题&#xff0c;共同打造基础软/硬件解决方案&#xff0c;吸引了1400多支团队同台竞技&#xff0c;贡献了一场精彩纷呈的创新…

Java小白找工作必须领悟的修仙秘籍(一)

当我们走出校园&#xff0c;步入社会&#xff0c;必须得找工作&#xff0c;那么作为it小白你必须拥有过硬的基础应用知识&#xff0c;才能慢慢的适应工作的节奏&#xff0c;以下内容则都是基础中的基础&#xff0c;需要全部进行掌握&#xff0c;因为这里可能有你面试时需要回答…

极坐标系下的交换积分次序

极坐标系下的交换积分次序 我把极坐标系下的交换积分次序总结为动静与静动之间的转换&#xff0c;下面通过一个例子感受一下 ρ 1 、 ρ 1 cos ⁡ θ \rho1、\rho1\cos\theta ρ1、ρ1cosθ ∫ 0 π / 2 d θ ∫ 1 1 cos ⁡ θ f ( ρ cos ⁡ θ , ρ sin ⁡ θ ) ρ d…

openAI发布基于ChatGPT的AI绘画模型DALL·E3,话说stable-diffusion还香吗?

前期的文章&#xff0c;我们介绍过stable-diffusion的相关操作&#xff0c;stable diffusion模型是Stability AI开源的一个text-to-image的扩散模型&#xff0c;其模型在速度与质量上面有了质的突破&#xff0c;玩家们可以在自己消费级GPU上面来运行此模型&#xff0c;本模型基…

2023年能跨平台同步的笔记软件

对于当今的职场人士来说&#xff0c;记录和管理大量的信息已经成为了日常工作中不可或缺的一部分。无论是会议笔记、读书笔记、重要工作任务还是工作注意事项&#xff0c;如何高效地记录和管理这些内容&#xff0c;成为了职场人士关注的焦点。 如何记录这些笔记内容更加简单方…

定时器的基本原理和应用

题目背景 利用51单片机的定时/计数器T0的模式1实现间隔定时&#xff0c;每隔1秒L1指示灯闪烁一下&#xff0c;也就是亮0.5秒&#xff0c;熄灭0.5秒&#xff1b;每隔10秒L8指示灯闪烁一下&#xff0c;也就是也就是亮5秒&#xff0c;熄灭5秒。 分析 计数初值。 定时/计数器&…

《C++ Primer》第5章 语句

参考资料&#xff1a; 《C Primer》第5版《C Primer 习题集》第5版 5.1 简单语句&#xff08;P154&#xff09; 在一个表达式的末尾加上 ; 就构成了表达式语句&#xff0c;其作用是执行表达式并丢弃结果。 空语句 由单独的 ; 构成的语句为空语句。空语句常用于语法上需要一…

Nuget 镜像源地址过期,腾旭镜像源地址替换

Nuget过期 国内镜像源地址ssl认证过期了。Nuget无法搜索&#xff0c;一直还原报错 解决方法&#xff0c;替换腾旭镜像源地址 tencent_mirrors https://mirrors.cloud.tencent.com/nuget/

婴幼儿腹泻的原因与应对

引言&#xff1a; 腹泻是婴幼儿常见的健康问题之一&#xff0c;尤其在早期生活阶段&#xff0c;由于他们的消化系统尚未完全发育&#xff0c;容易受到各种因素的影响。腹泻不仅给婴幼儿带来不适&#xff0c;还可能导致脱水和营养不良。因此&#xff0c;了解婴幼儿腹泻的原因是…