LeetCode第 114 题:二叉树展开为链表(C++)

114. 二叉树展开为链表 - 力扣(LeetCode)
在这里插入图片描述

关键点在于原地展开,如果不要求原地的话,直接中序遍历再生成链表就可以了。

要原地的话,应该就是用递归了,其实思路很简单,先保存右子树,然后把左子树接到右边,再把右子树接在左子树的最右节点,自上而下递归:

    1
   /  \
  2    5
 / \     \
3   4    6
//左子树插到右子树的位置
    1
      \
       2         5
      /  \         \
     3    4        6        
//右子树接到左子树最右节点
    1
     \
      2          
     / \          
    3   4  
           \
            5
              \
               6
            
 //自上而下,2的左子树插到右子树的位置
    1
      \
       2          
         \          
          3       4  
                     \
                      5
                        \
                         6   
        
 //右子树接到左子树最右节点
    1
     \
      2          
       \          
        3      
         \
          4  
           \
            5
             \
              6 
 .
 .
 .
class Solution {
public:
    void flatten(TreeNode* root) {
        if(!root)   return;
        while(root){
            if(!root->left){
                root = root->right;
                continue;
            } 
            auto left = root->left;
            while(left->right) left = left->right;//左子树最右节点
            left->right = root->right;//右子树接到左子树最右节点
            root->right = root->left;//左子树接到右子树位置
            root->left = NULL;//左子树置空

            root = root->right;
        }
    }
};

如果用递归来写:

class Solution {
public:
    void flatten(TreeNode* root) {
        if(!root)   return;//递归出口
        flatten(root->left);
        flatten(root->right);
        //现在可以认为左右子树都已经处理好了
        auto tmp = root->right;//临时保存右子树
        root->right = root->left;//左子树接到右边
        root->left = NULL;//左子树置空
        //寻找左洗子树的最右节点
        while(root->right)  root = root->right;
        root->right = tmp;.//右子树接到左子树的最右节点
    }
};

我们还可以进行后续遍历,自下而上:

可以看这个题解:详细通俗的思路分析,多解法 - 二叉树展开为链表 - 力扣(LeetCode)

class Solution {
public:
    //后续遍历
    TreeNode *pre = NULL;
    void flatten(TreeNode* root) {
        if(!root)    return;
        flatten(root->right);
        flatten(root->left);
        root->right = pre;
        root->left = NULL;//左子树置空
        pre = root;
    }
};

还可以借助栈来保存右子树,然后结合前序遍历:

class Solution {
public:
    void flatten(TreeNode* root) {
        if(!root)    return;
        stack<TreeNode*> stk;
        stk.push(root);
        TreeNode *pre = NULL;
        while(!stk.empty()){
            auto tmp = stk.top();
            stk.pop();
            if(pre){
                pre->right = tmp;
                pre->left = NULL;
            }
            if(tmp->right)  stk.push(tmp->right);
            if(tmp->left)   stk.push(tmp->left);
            pre = tmp;
        }
    }
};
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值