114. 二叉树展开为链表

首先是原地算法的定义:

算法原地工作的含义是指不需要任何额外的辅助,算法所需要的辅助空间不随着问题的规模而变化,是一个确定的值。

通过观察示例可以知道,我们可以猜想,大方向是前序遍历。

第一种思路:dfs。设置一个全局的指针(这种做法有点脱离原地算法,因为多开辟了一个指针变量)核心思想是拿到一个根节点以后,将其左右子树断开。然后将作为全局变量的右孩子指向刚断开左孩子和右孩子的根节点(flat->right=root)。形式上同前序遍历的递归形式。

//尝试使用前序遍历
class Solution {
public:
    TreeNode* flat; //这里设置flat可以帮忙辅助式地在原root的基础上进行增删。
    void dfs(TreeNode* root)
    {
      if(root==NULL)return;
      TreeNode* l=root->left;
      TreeNode* r=root->right;
      root->left=NULL;//不要忘记给左右节点置空
      root->right=NULL;
      flat->right=root;
      flat=root;//及时更新flat的值
      dfs(l);
      dfs(r);
    }  
    void flatten(TreeNode* root) {
    if(root==NULL) return;
    flat=root;
    TreeNode* l=root->left;
    TreeNode* r=root->right;
    flat->left=NULL;
    flat->right=NULL;
    dfs(l);//可以想象为什么是左右子树都要dfs一下
    dfs(r);
        
    }
};

 

 

  第二种方法是迭代的方法,我觉得不错的原因是用到了考研上的迭代寻找左子树的最右节点等一系列相似操作。

详见这篇博文的解法二 https://blog.csdn.net/thousa_ho/article/details/77961918

其中关键的的是找左子树的最右节点:

代码为while (p.right != null) { p = p.right }; 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值