zoukankan      html  css  js  c++  java
  • LeetCode——114. 二叉树展开为链表

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

    例如,给定二叉树

        1
       / 
      2   5
     /    
    3   4   6
    

    将其展开为:

    1
     
      2
       
        3
         
          4
           
            5
             
              6
    

    https://leetcode-cn.com/problems/flatten-binary-tree-to-linked-list/

    递归

    先利用 DFS 的思路找到最左子节点,然后回到其父节点,把其父节点和右子节点断开,将原左子结点连上父节点的右子节点上,然后再把原右子节点连到新右子节点的右子节点上,然后再回到上一父节点做相同操作。代码如下:

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

         1
        / 
       2   5
      /    
     3   4   6
    
         1
        / 
       2   5
           
         3   6
              
           4
    
       1
        
         2
          
           3
            
             4
              
               5
                
                 6
    

    c++

    class Solution {
    public:
        void flatten(TreeNode *root) {
            if (!root) return;
            if (root->left) flatten(root->left);
            if (root->right) flatten(root->right);
            TreeNode *tmp = root->right;
            root->right = root->left;
            root->left = NULL;
            while (root->right) root = root->right;
            root->right = tmp;
        }
    }; 
    

    java

    class Solution {
        TreeNode pre = null;
        public void flatten(TreeNode root) {
            if(root == null) return;
            flatten(root.right);
            flatten(root.left);
            root.right = pre;
            root.left = null;
            pre = root;        
        }
    }
    

    python

    class Solution:
        def flatten(self, root: TreeNode) -> None:
            def flatten(root):
                if root == None: return
                flatten(root.left)
                flatten(root.right)
                if root.left != None: # 后序遍历
                    pre = root.left # 令 pre 指向左子树
                    while pre.right: pre = pre.right # 找到左子树中的最右节点
                    pre.right = root.right # 令左子树中的最右节点的右子树 指向 根节点的右子树
                    root.right = root.left # 令根节点的右子树指向根节点的左子树
                    root.left = None # 置空根节点的左子树
                root = root.right # 令当前节点指向下一个节点
            flatten(root)
    

    非迭代

    这个方法是从根节点开始出发,先检测其左子结点是否存在,如存在则将根节点和其右子节点断开,将左子结点及其后面所有结构一起连到原右子节点的位置,把原右子节点连到元左子结点最后面的右子节点之后。代码如下:

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

         1
        / 
       2   5
      /    
     3   4   6
    
       1
        
         2
        / 
       3   4
            
             5
              
               6
               
       1
        
         2
          
           3
            
             4
              
               5
                
                 6
    

    c++

    class Solution {
    public:
        void flatten(TreeNode *root) {
            TreeNode *cur = root;
            while (cur) {
                if (cur->left) {  //左
                    TreeNode *p = cur->left;
                    while (p->right) p = p->right;
                    p->right = cur->right;
                    cur->right = cur->left;
                    cur->left = NULL;
                }
                cur = cur->right;
            }
        }
    };
    

    python

    class Solution:
        def flatten(self, root: TreeNode) -> None:
            while (root != None):
                if root.left != None:
                    most_right = root.left
                    while most_right.right != None: most_right = most_right.right
                    most_right.right = root.right
                    root.right = root.left
                    root.left = None
                root = root.right
            return
    

    前序迭代

    解法如下:

    c++

    class Solution {
    public:
        void flatten(TreeNode* root) {
            if (!root) return;
            stack<TreeNode*> s;
            s.push(root);
            while (!s.empty()) {
                TreeNode *t = s.top(); s.pop();
                if (t->left) {
                    TreeNode *r = t->left;
                    while (r->right) r = r->right;
                    r->right = t->right;
                    t->right = t->left;
                    t->left = NULL;
                }
                if (t->right) s.push(t->right);
            }
        }
    };
    
  • 相关阅读:
    01前端-html
    2-3程序流程
    2-2视频缓存池
    2-1图像像素格式深度理解
    3.1.1 文件系统介绍
    3.1.4 文件属性
    CentOS开放端口的方法
    宝塔linux面板命令大全
    如何卸载Win10 RS3上预装的office2016
    win10家庭版升级专业版的两种方法和密钥
  • 原文地址:https://www.cnblogs.com/wwj99/p/12418731.html
Copyright © 2011-2022 走看看