LeetCode - Flatten Binary Tree to Linked List


https://leetcode.com/problems/flatten-binary-tree-to-linked-list/
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
If you notice carefully in the flattened tree, each node's right child points to the next node of a pre-order traversal.
Recursive Version:


X. https://discuss.leetcode.com/topic/11444/my-short-post-order-traversal-java-solution-for-share
I would rename "prev" with "nxt" for the purpose of clarification
private TreeNode prev = null;

public void flatten(TreeNode root) {
    if (root == null)
        return;
    flatten(root.right);
    flatten(root.left);
    root.right = prev;
    root.left = null;
    prev = root;
}
X. http://bangbingsyb.blogspot.com/2014/11/leetcode-flatten-binary-tree-to-linked.html
假设某节点的左右子树T(root->left)和T(root->right)已经flatten成linked list了:

    1
  /    \
 2     5
  \       \
   3      6 <- rightTail
     \
      4  <- leftTail

如何将root、T(root->left)、T(root->right) flatten成一整个linked list?显而易见:

temp = root->right
root->right  = root->left
root->left = NULL
leftTail->right = temp

这里需要用到已经flatten的linked list的尾部元素leftTail, rightTail。所以递归返回值应该是生成的整个linked list的尾部。
需注意几个细节
ln 11:只有当左子树存在时才将它插入右子树中
ln 18-20:返回尾部元素时,需要特殊处理 (1) 有右子树的情况,(2) 无右子树但有左子树的情况,(3)左右子树均不存在的情况。
  TreeNode flatten(TreeNode root) {
    if (root == null)
      return null;

    TreeNode leftTail = flatten(root.left);
    TreeNode rightTail = flatten(root.right);

    if (root.left != null) {
      TreeNode temp = root.right;
      root.right = root.left;
      root.left = null;
      leftTail.right = temp;
    }

    if (rightTail != null)
      return rightTail;

    if (leftTail != null)
      return leftTail;

    return root;

  }

X. Pre-order
http://fisherlei.blogspot.com/2012/12/leetcode-flatten-binary-tree-to-linked.html
  TreeNode pre;

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

  }

X. http://bangbingsyb.blogspot.com/2014/11/leetcode-flatten-binary-tree-to-linked.html
从题目的例子马上发现其实就是preorder transverse整个tree,然后根据这个访问顺序,后访问到的节点成为先访问到的节点的右子节点。那么最不动脑的方法就是preorder transverse的时候把整个节点序列保存在一个vector中。最后再依次连起来。这个解法的空间复杂度包括了递归深度O(log n)和vector的空间O(n),所以总的空间复杂度是O(n)。
    void flatten(TreeNode *root) {
        if(!root) return;
        vector<TreeNode*> allNodes;
        preorder(root, allNodes);
        int n = allNodes.size();
        for(int i=0; i<n-1; i++) {
            allNodes[i]->left = NULL;
            allNodes[i]->right = allNodes[i+1];
        }
        allNodes[n-1]->left = allNodes[n-1]->right = NULL;
    }
    
    void preorder(TreeNode *root, vector<TreeNode*> &allNodes) {
        if(!root) return;
        allNodes.push_back(root);
        preorder(root->left, allNodes);
        preorder(root->right, allNodes);
    }
X. Noe efficient:
https://leetcode.com/problems/flatten-binary-tree-to-linked-list/discuss/36987/Straightforward-Java-Solution


public void flatten(TreeNode root) {
        if (root == null) return;
        
        TreeNode left = root.left;
        TreeNode right = root.right;
        
        root.left = null;
        
        flatten(left);
        flatten(right);
        
        root.right = left;
        TreeNode cur = root;
        while (cur.right != null) cur = cur.right;
        cur.right = right;
    }
This solution is based on recursion. We simply flatten left and right subtree and paste each sublist to the right child of the root. (don't forget to set left child to null)

From http://fisherlei.blogspot.com/2012/12/leetcode-flatten-binary-tree-to-linked.html

void flatten(TreeNode *root) {  
       // Start typing your C/C++ solution below  
       // DO NOT write int main() function  
       if(root == NULL)  
            return;  
       ConvertToLink(root);  
  }  
  TreeNode* ConvertToLink(TreeNode* node)  
  {  
       if(node->left == NULL && node->right == NULL)  
            return node;  
       TreeNode* rHead = NULL;  
       if(node->right != NULL)  
           rHead = ConvertToLink(node->right);               
       TreeNode* p = node;  
       if(node->left!=NULL)  
       {  
            TreeNode* lHead = ConvertToLink(node->left);   
            node->right = lHead;  
            lHead->left = NULL;  
            node->left = NULL;  
            while(p->right!=NULL)  
                 p = p->right;  
       }       
       if(rHead != NULL)  
       {  
            p->right = rHead;  
            rHead->left = NULL;  
       }  
       return node;  

  }
[已犯错误]
1. Line 13~14
    刚开始的时候,首先flatten左树,然后处理右树。但是这样会导致处理右树的时候,节点的值已经在处理树的时候被破坏了。比如树为{1,2,3},
     1
  /     \
2       3
如果先处理左树的话,当执行node->right = lhead的时候,右节点就已经被破坏了,node->right指向了2,而不是3。
1
   \
     2  (3)
当然,也可以用一个变量在处理左树前,保存右树地址。但是没必要,先处理右树就好了。
2. Line 22~23
    该循环是用于将p指针遍历到左树链表的最右节点。第一版时,这个循环是放在if语句以外,这就导致了,不必要的迭代了。比如当输入为{1,#,2}时,这个while循环会导致p指针遍历到右子树的最右节点,这显然是错的。
3. Line 20, 28
    不要忘了清空每一个指针,在新的链表中,左指针没必要保留
from http://www.darrensunny.me/leetcode-flatten-binary-tree-to-linked-list/
private TreeNode recursiveFlatten(TreeNode t) {
        if (t == null)      // Empty tree
            return null;
        // Recursively flatten its left and right subtrees
        TreeNode leftLeaf = recursiveFlatten(t.left);
        TreeNode rightLeaf = recursiveFlatten(t.right);
        if (leftLeaf == null && rightLeaf == null)    // The tree is a leaf itself
            return t;
        if (leftLeaf == null)    // Has only right subtree; already flattened
            return rightLeaf;
        if (rightLeaf == null) { // Has only left subtree; make it right
            t.right = t.left;
            t.left = null;
            return leftLeaf;
        }
        // Has both left and right subtrees
        // Put the left subtree in between the root and the right subtree
        TreeNode temp = t.right;
        t.right = t.left;
        t.left = null;
        leftLeaf.right = temp;
        return rightLeaf;
    }
Iterative Version: 
Use stack from http://www.programcreek.com/2013/01/leetcode-flatten-binary-tree-to-linked-list/
https://leetcode.com/problems/flatten-binary-tree-to-linked-list/discuss/36991/Accepted-simple-Java-solution-iterative
Go down through the left, when right is not null, push right to stack.
public void flatten(TreeNode root) {
        Stack<TreeNode> stack = new Stack<TreeNode>();
        TreeNode p = root;
 
        while(p != null || !stack.empty()){
 
            if(p.right != null){
                stack.push(p.right);
            }
 
            if(p.left != null){
                p.right = p.left;
                p.left = null;
            }else if(!stack.empty()){
                TreeNode temp = stack.pop();
                p.right=temp;
            }
 
            p = p.right;
        }
    }
Also read http://blog.csdn.net/perfect8886/article/details/20000083
https://discuss.leetcode.com/topic/5783/accepted-simple-java-solution-iterative
it is DFS so u need a stack. Dont forget to set the left child to null, or u'll get TLE. (tricky!)
   public void flatten(TreeNode root) {
        if (root == null) return;
        Stack<TreeNode> stk = new Stack<TreeNode>();
        stk.push(root);
        while (!stk.isEmpty()){
            TreeNode curr = stk.pop();
            if (curr.right!=null)  
                 stk.push(curr.right);
            if (curr.left!=null)  
                 stk.push(curr.left);
            if (!stk.isEmpty()) 
                 curr.right = stk.peek();
            curr.left = null;  // dont forget this!! 
        }
    }

O(N^2)
https://discuss.leetcode.com/topic/9936/straightforward-java-solution
public void flatten(TreeNode root) {
        if (root == null) return;
        
        TreeNode left = root.left;
        TreeNode right = root.right;
        
        root.left = null;
        
        flatten(left);
        flatten(right);
        
        root.right = left;
        TreeNode cur = root;
        while (cur.right != null) cur = cur.right;
        cur.right = right;
    }
This solution is based on recursion. We simply flatten left and right subtree and paste each sublist to the right child of the root. (don't forget to set left child to null)

X. Follow up
http://fisherlei.blogspot.com/2012/12/leetcode-flatten-binary-tree-to-linked.html
Update 08/25/2014  being asked this question today. But the interviewer asked for an in-order flatten.
Review previous solution. Actually, I made it too complicate. If travel this tree in pre-order, from the hint, it is easy to construct the linked list.

1:       void flatten(TreeNode *root) {  
2:            if(root == NULL) return;  
3:            TreeNode* right = root->right;  
4:            if(lastVisitedNode != NULL)  
5:            {  
6:                 lastVisitedNode->left = NULL;  
7:                 lastVisitedNode->right = root;  
8:            }  
9:            lastVisitedNode = root;  
10:            flatten(root->left);  
11:            flatten(right);  
12:       }  

pre-order is simple because the root always is the head of flatten list. But if flatten the tree with in-order sequence, need extra parameter to track the head and tail of each flattened sun-tree.
For example, below binary tree.

If we flatten it with in-order, the process should like below. And here I use the left pointer of head node to track the tail node.



1:  TreeNode* flatten(TreeNode *root) {  
2:       if (root == NULL) return NULL;  
3:       TreeNode* rightTree = root->right;  
4:       TreeNode* newHead = root;  
5:       TreeNode* leftList = flatten(root->left);  
6:       if (leftList != NULL)  
7:       {  
8:            newHead = leftList;  
9:            TreeNode* tail = leftList->left;  
10:            tail->right = root;  
11:            root->left = tail;  
12:            leftList->left = root;  
13:       }  
14:       TreeNode* rightList = flatten(rightTree);  
15:       if (rightList != NULL)  
16:       {  
17:            root->right = rightList;  
18:            newHead->left = rightList->left;  
19:            rightList->left = root;  
20:       }  
21:       return newHead;  
22:  }  

Read full article from LeetCode - Flatten Binary Tree to Linked List | Darren's Blog

Labels

LeetCode (1432) GeeksforGeeks (1122) LeetCode - Review (1067) Review (882) Algorithm (668) to-do (609) Classic Algorithm (270) Google Interview (237) Classic Interview (222) Dynamic Programming (220) DP (186) Bit Algorithms (145) POJ (141) Math (137) Tree (132) LeetCode - Phone (129) EPI (122) Cracking Coding Interview (119) DFS (115) Difficult Algorithm (115) Lintcode (115) Different Solutions (110) Smart Algorithm (104) Binary Search (96) BFS (91) HackerRank (90) Binary Tree (86) Hard (79) Two Pointers (78) Stack (76) Company-Facebook (75) BST (72) Graph Algorithm (72) Time Complexity (69) Greedy Algorithm (68) Interval (63) Company - Google (62) Geometry Algorithm (61) Interview Corner (61) LeetCode - Extended (61) Union-Find (60) Trie (58) Advanced Data Structure (56) List (56) Priority Queue (53) Codility (52) ComProGuide (50) LeetCode Hard (50) Matrix (50) Bisection (48) Segment Tree (48) Sliding Window (48) USACO (46) Space Optimization (45) Company-Airbnb (41) Greedy (41) Mathematical Algorithm (41) Tree - Post-Order (41) ACM-ICPC (40) Algorithm Interview (40) Data Structure Design (40) Graph (40) Backtracking (39) Data Structure (39) Jobdu (39) Random (39) Codeforces (38) Knapsack (38) LeetCode - DP (38) Recursive Algorithm (38) String Algorithm (38) TopCoder (38) Sort (37) Introduction to Algorithms (36) Pre-Sort (36) Beauty of Programming (35) Must Known (34) Binary Search Tree (33) Follow Up (33) prismoskills (33) Palindrome (32) Permutation (31) Array (30) Google Code Jam (30) HDU (30) Array O(N) (29) Logic Thinking (29) Monotonic Stack (29) Puzzles (29) Code - Detail (27) Company-Zenefits (27) Microsoft 100 - July (27) Queue (27) Binary Indexed Trees (26) TreeMap (26) to-do-must (26) 1point3acres (25) GeeksQuiz (25) Merge Sort (25) Reverse Thinking (25) hihocoder (25) Company - LinkedIn (24) Hash (24) High Frequency (24) Summary (24) Divide and Conquer (23) Proof (23) Game Theory (22) Topological Sort (22) Lintcode - Review (21) Tree - Modification (21) Algorithm Game (20) CareerCup (20) Company - Twitter (20) DFS + Review (20) DP - Relation (20) Brain Teaser (19) DP - Tree (19) Left and Right Array (19) O(N) (19) Sweep Line (19) UVA (19) DP - Bit Masking (18) LeetCode - Thinking (18) KMP (17) LeetCode - TODO (17) Probabilities (17) Simulation (17) String Search (17) Codercareer (16) Company-Uber (16) Iterator (16) Number (16) O(1) Space (16) Shortest Path (16) itint5 (16) DFS+Cache (15) Dijkstra (15) Euclidean GCD (15) Heap (15) LeetCode - Hard (15) Majority (15) Number Theory (15) Rolling Hash (15) Tree Traversal (15) Brute Force (14) Bucket Sort (14) DP - Knapsack (14) DP - Probability (14) Difficult (14) Fast Power Algorithm (14) Pattern (14) Prefix Sum (14) TreeSet (14) Algorithm Videos (13) Amazon Interview (13) Basic Algorithm (13) Codechef (13) Combination (13) Computational Geometry (13) DP - Digit (13) LCA (13) LeetCode - DFS (13) Linked List (13) Long Increasing Sequence(LIS) (13) Math-Divisible (13) Reservoir Sampling (13) mitbbs (13) Algorithm - How To (12) Company - Microsoft (12) DP - Interval (12) DP - Multiple Relation (12) DP - Relation Optimization (12) LeetCode - Classic (12) Level Order Traversal (12) Prime (12) Pruning (12) Reconstruct Tree (12) Thinking (12) X Sum (12) AOJ (11) Bit Mask (11) Company-Snapchat (11) DP - Space Optimization (11) Dequeue (11) Graph DFS (11) MinMax (11) Miscs (11) Princeton (11) Quick Sort (11) Stack - Tree (11) 尺取法 (11) 挑战程序设计竞赛 (11) Coin Change (10) DFS+Backtracking (10) Facebook Hacker Cup (10) Fast Slow Pointers (10) HackerRank Easy (10) Interval Tree (10) Limited Range (10) Matrix - Traverse (10) Monotone Queue (10) SPOJ (10) Starting Point (10) States (10) Stock (10) Theory (10) Tutorialhorizon (10) Kadane - Extended (9) Mathblog (9) Max-Min Flow (9) Maze (9) Median (9) O(32N) (9) Quick Select (9) Stack Overflow (9) System Design (9) Tree - Conversion (9) Use XOR (9) Book Notes (8) Company-Amazon (8) DFS+BFS (8) DP - States (8) Expression (8) Longest Common Subsequence(LCS) (8) One Pass (8) Quadtrees (8) Traversal Once (8) Trie - Suffix (8) 穷竭搜索 (8) Algorithm Problem List (7) All Sub (7) Catalan Number (7) Cycle (7) DP - Cases (7) Facebook Interview (7) Fibonacci Numbers (7) Flood fill (7) Game Nim (7) Graph BFS (7) HackerRank Difficult (7) Hackerearth (7) Inversion (7) Kadane’s Algorithm (7) Manacher (7) Morris Traversal (7) Multiple Data Structures (7) Normalized Key (7) O(XN) (7) Radix Sort (7) Recursion (7) Sampling (7) Suffix Array (7) Tech-Queries (7) Tree - Serialization (7) Tree DP (7) Trie - Bit (7) 蓝桥杯 (7) Algorithm - Brain Teaser (6) BFS - Priority Queue (6) BFS - Unusual (6) Classic Data Structure Impl (6) DP - 2D (6) DP - Monotone Queue (6) DP - Unusual (6) DP-Space Optimization (6) Dutch Flag (6) How To (6) Interviewstreet (6) Knapsack - MultiplePack (6) Local MinMax (6) MST (6) Minimum Spanning Tree (6) Number - Reach (6) Parentheses (6) Pre-Sum (6) Probability (6) Programming Pearls (6) Rabin-Karp (6) Reverse (6) Scan from right (6) Schedule (6) Stream (6) Subset Sum (6) TSP (6) Xpost (6) n00tc0d3r (6) reddit (6) AI (5) Abbreviation (5) Anagram (5) Art Of Programming-July (5) Assumption (5) Bellman Ford (5) Big Data (5) Code - Solid (5) Code Kata (5) Codility-lessons (5) Coding (5) Company - WMware (5) Convex Hull (5) Crazyforcode (5) DFS - Multiple (5) DFS+DP (5) DP - Multi-Dimension (5) DP-Multiple Relation (5) Eulerian Cycle (5) Graph - Unusual (5) Graph Cycle (5) Hash Strategy (5) Immutability (5) Java (5) LogN (5) Manhattan Distance (5) Matrix Chain Multiplication (5) N Queens (5) Pre-Sort: Index (5) Quick Partition (5) Quora (5) Randomized Algorithms (5) Resources (5) Robot (5) SPFA(Shortest Path Faster Algorithm) (5) Shuffle (5) Sieve of Eratosthenes (5) Strongly Connected Components (5) Subarray Sum (5) Sudoku (5) Suffix Tree (5) Swap (5) Threaded (5) Tree - Creation (5) Warshall Floyd (5) Word Search (5) jiuzhang (5)

Popular Posts