Flatten Binary Tree to Linked List

Question: 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
Hints:

If you notice carefully in the flattened tree, each node's right child points to the next node of a pre-order traversal.


Solution 1: 一般性的 Binary Tree Preorder Traversal

 1 public void flatten(TreeNode root) {
 2     if(root == null) {
 3         return;
 4     }
 5     
 6     ArrayList<TreeNode> list = new ArrayList<>();
 7     helper(root, list);
 8     
 9     list.get(0).left = null;
10     for(int i = 1; i < list.size(); i++) {
11         list.get(i).left = null;
12         list.get(i-1).right = list.get(i);
13     }
14 }
15 
16 private void helper(TreeNode root, ArrayList<TreeNode> list) {
17     if(root == null) {
18         return;
19     }
20     
21     list.add(root);
22     helper(root.left, list);
23     helper(root.right, list);
24 }

Sulotion 2: Refer from Code Ganker

 1 public void flatten(TreeNode root) {
 2     if(root == null) {
 3         return;
 4     }
 5     
 6     ArrayList<TreeNode> list = new ArrayList<>();
 7     list.add(null);
 8     helper(root, list);
 9 }
10 
11 private void helper(TreeNode root, ArrayList<TreeNode> list) {
12     if(root == null) {
13         return;
14     }
15     
16     TreeNode right = root.right;    // Attention here
17     if(list.get(0) != null) {
18         list.get(0).left = null;
19         list.get(0).right = root;
20     }
21     
22     list.set(0, root);
23     helper(root.left, list);
24     helper(right, list);
25 }

这里的 ArrayList 是 Code Ganker 中经常使用的处理方式,实质就是一个 Reference to an object with updated Instance variable. Wrapper Class with field variable 也可以实现这项功能。

这里的 list variable 一直只包含一个 TreeNode,这个 TreeNode 是已经得到、不断被更新的 flattened LinkedList 的最后一个 Element。

Attention:

  • Line #16: 此刻的 root.right 必须使用 local variable 保存其 Reference,因为 经过 Line #23 之后 root.right 已经是 原本的 root.left。
  • Line #23 与 #24 中的 list 所指向的 TreeNode 是不同的。
    • Line #23 中 list 指向的是 TreeNode root
    • Line #24 中 list 指向的是 Preorder 中 TreeNode right 的前一个 TreeNode,也就是已经处理的 flattened LinkedList 的最后一个 Element。
    • 该处也是 使用 List 来包含 TreeNode,而不是直接传递 TreeNode prev 的原因
 
下面是 试图 采用 TreeNode prev 来代替 ArrayList<TreeNode> list 的错误代码。错误原因,上面分析和下面的代码中已经详述:
 1 public class Solution {
 2     public void flatten(TreeNode root) {
 3         if(root == null) {
 4             return;
 5         }
 6         
 7         helper(root, null);
 8     }
 9     
10     private void helper(TreeNode root, TreeNode prev) {
11         if(root == null) {
12             return;
13         }
14         
15         TreeNode right = root.right;
16         if(prev != null) {
17             prev.right = root;
18             prev.left = null;
19         }
20         
21         prev = root;
22         helper(root.left, prev);
23         helper(right, prev);    // 这里的 prev 仍是 root,实际上应该使用 更新过得 prev
24     }
25 }

Solution 3: 使用 field variable TreeNode prev 来代替 ArrayList<TreeNode> list

 1 public class Solution {
 2     // field variable to replace ArrayList<TreeNode>
 3     public TreeNode prev = null;
 4     
 5     public void flatten(TreeNode root) {
 6         if(root == null) {
 7             return;
 8         }
 9         
10         helper(root);
11     }
12     
13     private void helper(TreeNode root) {
14         if(root == null) {
15             return;
16         }
17         
18         TreeNode right = root.right;
19         if(prev != null) {
20             prev.right = root;
21             prev.left = null;
22         }
23         
24         prev = root;
25         helper(root.left);
26         helper(right);
27     }
28 }
 
原文地址:https://www.cnblogs.com/Phoenix-Fearless/p/5109248.html