• 【力客热题HOT100】-【044】114 二叉树展开为链表


    重点:

    (1)前序遍历:存储前序遍历序列,然后建立新链表;迭代和递归两种实现;

    (2)寻找前驱节点空间复杂度O(1)

    114. 二叉树展开为链表

    难度中等

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

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

    示例 1:

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

    示例 2:

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

    示例 3:

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

    提示:

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

    进阶:你可以使用原地算法(O(1) 额外空间)展开这棵树吗?

    解析:

    方法1:前序遍历

    前序遍历之后,把节点顺序存储下来,然后建立链表即可。左指针指向nullptr,右指针指向下一个元素;

    方法2:寻找前驱节点

    对于一个节点,如果其没有左子树,只有右子树,那么该节点就不需要展开操作。如果其有左子树,那么对于其右子树来说,左子树的最后一个节点被访问之后,该节点的右子树也即将被访问。这说明左子树的最后一个节点是右子树的前驱节点,也是该节点的前驱节点(因为是先序遍历)。那么问题转化为寻找前驱节点。

    对于一个左子树非空的节点Anode,我们寻找其左子树C最后一个节点,就寻找其最右边的节点B。找到之后,将A的右子树连接到B的右子树Bnode->right=C,然后将左子树C连接到A的右子树Anode->right=C,然后Anode->left=nullptr。此时节点A只有右子树。那么寻找其右子树的第一个节点,进行再次操作。

    代码:

    1. class Solution {
    2. public:
    3. void flatten(TreeNode* root) {
    4. vector vec;
    5. stack stk;
    6. while(!stk.empty()||root!=nullptr){
    7. while(root!=nullptr){
    8. stk.push(root);
    9. vec.push_back(root);
    10. root=root->left;
    11. }
    12. root=stk.top();
    13. stk.pop();
    14. root=root->right;
    15. }
    16. int size=vec.size();
    17. for(int i=1;i
    18. TreeNode *pre=vec.at(i-1),*cur=vec.at(i);
    19. pre->left=nullptr;
    20. pre->right=cur;
    21. }
    22. }
    23. };
    1. class Solution {
    2. public:
    3. void flatten(TreeNode* root) {
    4. TreeNode *cur=root;
    5. while(cur!=nullptr){
    6. if(cur->left!=nullptr){
    7. auto next=cur->left;//即将链接到cur的右子树
    8. auto pressdor=next;
    9. while(pressdor->right!=nullptr)
    10. pressdor=pressdor->right;
    11. pressdor->right=cur->right;
    12. cur->left=nullptr;
    13. cur->right=next;
    14. }
    15. cur=cur->right;
    16. }
    17. }
    18. };
  • 相关阅读:
    基于Docker的深度学习环境NVIDIA和CUDA部署以及WSL和linux镜像问题
    网络安全-端口信息收集
    MySQL数据库UDF提权学习
    [论文阅读] 颜色迁移-N维pdf迁移
    【vue3】消息的订阅与发布
    【C++深入浅出】类和对象下篇
    WebAssembly学习笔记(一)
    想学设计模式、想搞架构设计,先学学 UML 系统建模吧
    一键到位「GitHub 热点速览 v.22.32」
    力扣刷题学习SQL篇——1-6 删除(删除重复的电子邮箱——临时表实现/连表实现)
  • 原文地址:https://blog.csdn.net/zhuge2017302307/article/details/126057570