zoukankan      html  css  js  c++  java
  • 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 };

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

  • 相关阅读:
    使用JFileChooser实现在指定文件夹下批量添加根据“数字型样式”或“非数字型样式”命令的文件夹
    51Nod 1376 最长递增子序列的数量 (DP+BIT)
    POJ 2728 Desert King (最优比率树)
    UVa 11280 Flying to Fredericton (DP + Dijkstra)
    UVa 11367 Full Tank? (DP + Dijkstra)
    UVa 10269 Adventure of Super Mario (Floyd + DP + BFS)
    UVaLive 4452 The Ministers' Major Mess (TwoSat)
    UVa 11294 Wedding (TwoSat)
    HDU 3247 Resource Archiver (AC自动机+BFS+状压DP)
    HDU 5957 Query on a graph (拓扑 + bfs序 + 树剖 + 线段树)
  • 原文地址:https://www.cnblogs.com/ariel-dreamland/p/9162548.html
Copyright © 2011-2022 走看看