zoukankan      html  css  js  c++  java
  • [LeetCode#114]Flatten Binary Tree to Linked List

    The problem:

    Given a binary tree, flatten it to a linked list in-place.

    For example,
    Given

             1
            / 
           2   5
          /    
         3   4   6
    

    The flattened tree should look like:

       1
        
         2
          
           3
            
             4
              
               5
                
                 6
    

     

    A wrong solution :

    public class Solution {
        public void flatten(TreeNode root) {
            if (root == null)
                return;
        
            ArrayList<TreeNode> pre = new ArrayList<TreeNode>();
            TreeNode dummy = new TreeNode(0); //use a dummy node for wirtting invariant
            pre.add(dummy);
            helper(root, pre);
        }
        
        private void helper(TreeNode cur, ArrayList<TreeNode> pre) {
            
            if (cur == null)
                return;
            
            TreeNode pre_node = pre.get(0);
            pre_node.left = null;
            pre_node.right = cur;
            
            pre.set(0, cur);
            helper(cur.left, pre);//this could change the right child value to cur, before reaching the next nextstatement.
            helper(cur.right, pre);
        }
    }

    An analyssis for the error:

    This question could be easily solved by using recursion, but when writing the program, we might introduce a big pitfall.
    Let's firstly consdiering the following buggy code:
    
        private void helper(TreeNode cur, ArrayList<TreeNode> pre) {
            
            if (cur == null)
                return;
            
            TreeNode pre_node = pre.get(0);
            pre_node.left = null;
            pre_node.right = cur;
            
            pre.set(0, cur);
            helper(cur.left, pre);
            helper(cur.right, pre);
        }
     
    The buggy code looks extraordinarily fine, if we thinking it from the perspective of non-recursion program.
    A big pitfall:
    1        helper(cur.left, pre); //we call the recursive function
    2        helper(cur.right, pre);
    the statement 1 would change the value of cur node.(even it does not change current pointer)
    in : 
    1.        pre_node.left = null;
    2.        pre_node.right = cur;
    This would lead to a infinite loop, thus result in stack overflow.
    The classic way to solve this problem is to keep a copy of left child and right child's pointer copy.
            TreeNode left = cur.left;
            TreeNode right = cur.right;
    Thus any recursion in the lower level would not affect current level's value.(it's very important!!!)

    My accepted solution:

    public class Solution {
        public void flatten(TreeNode root) {
            if (root == null)
                return;
        
            ArrayList<TreeNode> pre = new ArrayList<TreeNode>();
            TreeNode dummy = new TreeNode(0); //use a dummy node for wirtting invariant
            pre.add(dummy);
            helper(root, pre);
        }
        
        private void helper(TreeNode cur, ArrayList<TreeNode> pre) {
            
            if (cur == null)
                return;
            
            TreeNode pre_node = pre.get(0);
            pre_node.left = null;
            pre_node.right = cur;
            
            TreeNode left = cur.left;
            TreeNode right = cur.right;
            
            pre.set(0, cur);
            helper(left, pre);
            helper(right, pre);
        }
    }
  • 相关阅读:
    .Proto 文件转换成.cs文件
    C# 委托和事件
    C# 对word (03、07)的相关操作
    程序中记录日志的封装类
    压缩文件程.ZIP
    xml和对象直接的序列化和反序列化
    C#判断两个日期是否在同一周,某日期是本月的第几周
    vs2008 C# 单元测试
    解压缩.zip文件
    记录一次曲折的维护-重构过程
  • 原文地址:https://www.cnblogs.com/airwindow/p/4217602.html
Copyright © 2011-2022 走看看