LeetCode(114): 二叉树展开为链表

Posted Ariel_一只猫的旅行

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode(114): 二叉树展开为链表相关的知识,希望对你有一定的参考价值。

Medium!

题目描述:

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

例如,给定二叉树

    1
   /   2   5
 /    3   4   6

将其展开为:

1
   2
       3
           4
               5
                   6

解题思路:

这道题要求把二叉树展开成链表,根据展开后形成的链表的顺序分析出是使用先序遍历,那么只要是数的遍历就有递归和非递归的两种方法来求解,这里我们也用两种方法来求解。

首先来看递归版本的,思路是先利用DFS的思路找到最左子节点,然后回到其父节点,把其父节点和右子节点断开,将原左子结点连上父节点的右子节点上,然后再把原右子节点连到新右子节点的右子节点上,然后再回到上一父节点做相同操作。

C++解法一:

 1 // Recursion
 2 class Solution {
 3 public:
 4     void flatten(TreeNode *root) {
 5         if (!root) return;
 6         if (root->left) flatten(root->left);
 7         if (root->right) flatten(root->right);
 8         TreeNode *tmp = root->right;
 9         root->right = root->left;
10         root->left = NULL;
11         while (root->right) root = root->right;
12         root->right = tmp;
13     }
14 };

例如,对于下面的二叉树,上述算法的变换的过程如下:

技术分享图片
     1
    /    2   5
  /     3   4   6

     1
    /    2   5
            3   6
          
       4

   1
         2
             3
                 4
                     5
                         6
技术分享图片

下面我们再来看非迭代版本的实现,这个方法是从根节点开始出发,先检测其左子结点是否存在,如存在则将根节点和其右子节点断开,将左子结点及其后面所有结构一起连到原右子节点的位置,把原右子节点连到原左子结点最后面的右子节点之后。

C++解法二:

 1 // Non-recursion
 2 class Solution {
 3 public:
 4     void flatten(TreeNode *root) {
 5         TreeNode *cur = root;
 6         while (cur) {
 7             if (cur->left) {
 8                 TreeNode *p = cur->left;
 9                 while (p->right) p = p->right;
10                 p->right = cur->right;
11                 cur->right = cur->left;
12                 cur->left = NULL;
13             }
14             cur = cur->right;
15         }
16     }
17 };

例如,对于下面的二叉树,上述算法的变换的过程如下:

技术分享图片
     1
    /    2   5
  /     3   4   6

   1
         2
    /    3   4
                 5
                     6
           
   1
         2
             3
                 4
                     5
                         6
技术分享图片

前序迭代解法如下:

C++解法三:

 1 class Solution {
 2 public:
 3     void flatten(TreeNode* root) {
 4         if (!root) return;
 5         stack<TreeNode*> s;
 6         s.push(root);
 7         while (!s.empty()) {
 8             TreeNode *t = s.top(); s.pop();
 9             if (t->left) {
10                 TreeNode *r = t->left;
11                 while (r->right) r = r->right;
12                 r->right = t->right;
13                 t->right = t->left;
14                 t->left = NULL;
15             }
16             if (t->right) s.push(t->right);
17         }
18     }
19 };

此题还可以延伸到用中序,后序,层序的遍历顺序来展开原二叉树,分别又有其对应的递归和非递归的方法,有兴趣的童鞋可以自行实现。

以上是关于LeetCode(114): 二叉树展开为链表的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode第114题—二叉树展开为链表—Python实现

leetcode 114. 二叉树展开为链表(dfs)

[LeetCode] 114. 二叉树展开为链表 ☆☆☆(深度遍历)

⭐算法入门⭐《二叉树》中等01 —— LeetCode 114. 二叉树展开为链表

[LeetCode] 114. 二叉树展开为链表

LeetCode(114): 二叉树展开为链表