考研算法练习二:二叉树展开为链表

二叉树展开为链表

在这里插入图片描述
本题我采用了两种方法来做,

方法一,时间复杂度O(N),空间复杂度O(K),K是符合条件的结点的个数,最坏情况是N,最好情况是0

每次遍历一个结点的时候,如果该结点的左子树不为空,则交换左右子树,并且再交换后,左子树不为空,则将交换后左子树的父节点(也就是当前结点)保存到栈当中
如果右子树为空且左子树为空,判断栈内是否还有元素,如果没有,则退出递归,如果有,则取出栈顶树结点的指针,将本次操作结点的右子树赋值为栈顶结点的左子树,并且让栈顶结点的左子树赋值为空,完成后将该栈顶结点出栈

/**
 * 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:

    stack<TreeNode*> cache_stack;

	// 交换结点的左右子树
    void swapNode(TreeNode* node){
        TreeNode * temp = node->left;
        node->left = node->right;
        node->right = temp;
    }

    void orderNode(TreeNode* now){
        if(now->left != NULL){
            swapNode(now);
            if(now->left != NULL)
                cache_stack.push(now);
        }
        else if(now->right == NULL){
            if(cache_stack.empty())
                return;
            now->right = cache_stack.top()->left;
            cache_stack.top()->left = NULL;
            cache_stack.pop();
        }
        orderNode(now->right);
    }

    // 先序遍历折叠到右子树, 无法直接替换掉root,
    // 只能在原基础上修改掉 root 的左右子树的分布
    void flatten(TreeNode* root) {
        if(root == nullptr) return;
        orderNode(root);
    }
};

方法一,时间复杂度O(N),空间复杂度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:

    TreeNode* best_right = nullptr;
    void flatten(TreeNode* root) {
        if (root == nullptr) return;
        flatten(root->right);
        flatten(root->left);
        root->right = best_right;
        root->left = nullptr;
        best_right = root;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

凌晨小街

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值