首页 > 其他 > 详细

LeetCode | 114. 二叉树展开为链表

时间:2019-10-25 14:41:18      阅读:84      评论:0      收藏:0      [点我收藏+]

原题Medium):

  给定一个二叉树,原地将它展开为链表。

  技术分享图片

  根据题意,原地展开的意思是,按照中序遍历的顺序(中左右)把二叉树的结点逐一放到树的右节点上。

 

思路:

  我们已经知道,展开为链表后各节点顺序就是二叉树中序遍历的顺序,那么于一个节点而言,展开后,原本在其左子树节点肯定在原本其右子树的前面,例如:

技术分享图片

  其展开后节点2肯定在结点3前面。结果为:技术分享图片

  那么,用左节点取代右节点的位置,这于根结点而言,应该是没错的,是合乎顺序的,但是在这之前,我们肯定要考虑右节点的去向,我们可以以题目的例子为例:技术分享图片

 

 

   我们用左子树取代右子树,右子树暂时孤立,即:

技术分享图片

 

  那么按照中序遍历的顺序(节点内的数字就代表中序遍历的顺序),这右子树应该落在哪里呢?显然,应该节点4的右节点上:

技术分享图片

 

  而于根结点1而言,节点4是一个什么节点呢?我们能否根据特征找到这个节点然后把右子树接上去呢?其实我们要找的就是根节点的左子树的最右节点(节点4就是最右节点),按照中序遍历的顺序,这个最右节点就是在遍历到根节点之前的最后一个节点(就是说遍历完该节点后下一个被遍历的节点就是根节点),那么把右子树接到该最右节点的右子树上,就非常合理了。至于怎么找到它也非常容易,因为我们已经知道它是左子树的最右节点了。从左子树的第一个节点开始一直往其右节点遍历,直到右节点为空。

  再经历了上述的变换后,我们还没有解决问题,可以看到,虽然节点1的下的所有节点已经移动到右子树,但右子树里仍有不合题意的节点,显然需要我们进入右子节点,以节点2为根节点,继续考虑其左右子树的情况,进行类似的变换。可以得知,这是递归的思路,但实现的方法可以是递归,也可以不是递归。

 1 void flatten(TreeNode* root) {
 2     while (root != nullptr) {
 3         if (root->left != nullptr) {
 4             auto most_right = root->left; // 如果左子树不为空, 那么就先找到左子树的最右节点
 5             while (most_right->right != nullptr) most_right = most_right->right; // 找最右节点
 6             most_right->right = root->right; // 然后将跟的右孩子放到最右节点的右子树上
 7             root->right = root->left; // 这时候跟的右孩子可以释放, 因此我令左孩子放到右孩子上
 8             root->left = nullptr; // 将左孩子置为空
 9         }
10         root = root->right; // 继续下一个节点
11     }
12     return;
13 }

技术分享图片

LeetCode | 114. 二叉树展开为链表

原文:https://www.cnblogs.com/MisakiJH/p/11737803.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!