【Leetcode二叉树】114. 二叉树展开为链表

本文详细探讨了LeetCode 1141题目的四种解法,包括前序遍历递归建树、迭代建树、同步进行前序遍历与展开以及寻找前驱节点。通过实例和代码解析,展示了不同策略在解决扁平化二叉树问题上的优劣和空间复杂度特点。
摘要由CSDN通过智能技术生成

Leetcode114

1.问题描述

在这里插入图片描述

2.解决方案

题解链接

解法一:前序遍历加递归建树

先序遍历没什么可说的,然后就是递归建树,递归中把这种边界条件一定要想清楚了,把过程找几个比较一般的例子和极端的例子分析了就很容易了,递归建立树就按递归的套路来就好,重要的边界条件。

if(q.size()==0) return;
if(root== nullptr) root=new TreeNode;
class Solution {
public:
    queue<int> q;
    void preInorder(TreeNode* root){
        if(root== nullptr) return;

        q.push(root->val);
        preInorder(root->left);
        preInorder(root->right);
    }
    void build(TreeNode*& root){
        if(q.size()==0) return;
        if(root== nullptr) root=new TreeNode;
        
        root->val=q.front();
        q.pop();
        root->left= nullptr;
        build(root->right);
    }
    void flatten(TreeNode* root) {
        preInorder(root);
        build(root);
    }
};

解法二:前序遍历加迭代建树

这个优势在于把节点指针放入vector中,而且使用at函数而不是[]运算符,然后for循环设计的很巧妙,第一次取 0 1 第二次取 1 2 正好交替取节点,有个衔接正好 然后建树,迭代的技巧可取。

class Solution1 {
public:
    void preorderTraversal(TreeNode* root, vector<TreeNode*> &l) {
        if (root != NULL) {
            l.push_back(root);
            preorderTraversal(root->left, l);
            preorderTraversal(root->right, l);
        }
    }
    void flatten(TreeNode* root) {
        vector<TreeNode*> l;
        preorderTraversal(root, l);
        
        //迭代建树
        int n = l.size();
        for (int i = 1; i < n; i++) {
            //第一次取 0 1 第二次取 1 2 正好交替取节点,有个衔接正好 然后建树
            TreeNode *prev = l.at(i - 1), *curr = l.at(i);
            prev->left = nullptr;
            prev->right = curr;
        }
    }
};

解法三:前序遍历和展开同步进行(还没看)

在这里插入图片描述

class Solution {
public:
    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;
            if (right != nullptr) {
                stk.push(right);
            }
            if (left != nullptr) {
                stk.push(left);
            }
            prev = curr;
        }
    }
};


解法四:寻找前驱节点(还没看看一下空间复杂度优秀)

在这里插入图片描述

class Solution {
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;
        }
    }
};

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值