114. 二叉树展开为链表【 力扣(LeetCode) 】

零、LeetCode 原题


114. 二叉树展开为链表

一、题目描述

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

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

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

二、测试用例

示例 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

三、解题思路

3.1 栈

  1. 基本思路:
      使用栈进行先序遍历,然后一个一个连接起来;
  2. 具体思路:
    • 根入栈;
    • 只要栈非空:
      • 弹出栈顶元素,将栈顶元素拼接到链表尾部;
      • 只要右子树非空,将右子树压入栈;
      • 只要左子树非空,将左子树压入栈;

3.2 找前驱(优化空间复杂度)

  1. 基本思路:
      找到右子树的前驱,然后拼接到其后面;然后再将每个结点转为链表;
  2. 具体思路:
    • 遍历链表:
      • 如果左子树非空,那么左子树最右节点就是右子树的前驱,
        • 找到前驱并将右子树拼接到后面;
        • 将左子树移动到右子树位置,左子树设置为空;
      • 如果左子树为空,则右子树的前驱就是根,所以不做处理;

四、参考代码

4.1 栈

时间复杂度: O ( n ) \Omicron(n) O(n)
空间复杂度: O ( h ) \Omicron(h) O(h)【 弹出一个元素,最多压入两个元素,而这样的情况只会发生在添加子树时,一但不添加子树,就只会弹出,所以最坏情况就是2倍的树高;如果树退化为线性,则h=n

/**
 * 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 flatten(TreeNode* root) {
    
    
        if (!root)
            return;
        stack<TreeNode*> s;
        TreeNode* head = new TreeNode();

        s.push(root);
        while (!s.empty()) {
    
    
            TreeNode* p = s.top();
            s.pop();
            head->right = p;
            head->left = nullptr;
            head = head->right;
            if (p->right) {
    
    
                s.push(p->right);
            }
            if (p->left) {
    
    
                s.push(p->left);
            }
        }
    }
};

4.2 找前驱(优化空间复杂度)

时间复杂度: O ( n ) \Omicron(n) O(n)
空间复杂度: O ( 1 ) \Omicron(1) O(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 {
    
    
public:
    void flatten(TreeNode* root) {
    
    
        if (!root)
            return;
        TreeNode* p = root;

        while (p) {
    
    
            TreeNode* q = p->left;
            if (q) {
    
    
                while (q->right) {
    
    
                    q = q->right;
                }
                q->right = p->right;
                p->right = p->left;
                p->left = nullptr;
            }
            p = p->right;
        }
    }
};

猜你喜欢

转载自blog.csdn.net/yyh520025/article/details/143109550