114. Flatten Binary Tree to Linked List

Flatten a binary tree to a fake "linked list" in pre-order traversal.

Here we use the right pointer in TreeNode as the next pointer in ListNode.

For example,
Given
         1
        / \
       2   5
      / \   \
     3   4   6
 

The flattened tree should look like:

   1
    \
     2
      \
       3
        \
         4
          \
           5
            \
             6
 

 

分析:

把所有的树节点按照PRE-ORDER的顺序存在ArrayList里面,然后遍历ArrayList里的节点,调整它们的left and right child指针。

 1 /**
 2  * Definition of TreeNode:
 3  * public class TreeNode {
 4  *     public int val;
 5  *     public TreeNode left, right;
 6  *     public TreeNode(int val) {
 7  *         this.val = val;
 8  *         this.left = this.right = null;
 9  *     }
10  * }
11  */
12 public class Solution {
13     /**
14      * @param root: a TreeNode, the root of the binary tree
15      * @return: nothing
16      * cnblogs.com/beiyeqingteng
17      */
18     public void flatten(TreeNode root) {
19         // write your code here
20         ArrayList<TreeNode> list = new ArrayList<TreeNode>();
21         preOrder(root, list);
22         
23         for (int i = 0; i < list.size(); i++) {
24             list.get(i).left = null;
25             if (i == list.size() - 1) {
26                 list.get(i).right = null;
27             } else {
28                 list.get(i).right = list.get(i + 1);
29             }
30         }
31     }
32     
33     public void preOrder(TreeNode root, ArrayList<TreeNode> list) {
34         if (root != null) {
35             list.add(root);
36             preOrder(root.left, list);
37             preOrder(root.right, list);
38         }
39     }
40 }

 自己后来写出的方法:

 1 public class Solution {
 2 
 3     public void flatten(TreeNode root) {
 4         helper(root);
 5     }
 6     
 7     public TreeNode helper(TreeNode root) {
 8         if (root == null) return root;
 9         TreeNode leftHead = helper(root.left);
10         TreeNode rightHead = helper(root.right);
11         root.left = null;
12         if (leftHead != null) {
13             root.right = leftHead;
14             TreeNode current = root;
15             while (current.right != null) {
16                 current = current.right;
17             }
18             current.right = rightHead;
19         } 
20         return root;
21     }
22 }

 

还有一种是递归的方式,下面的方法参考了另一个网友的做法,觉得这种方法非常容易理解,而且具有一般性。

 

解法2:递归构建

假设某节点的左右子树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的尾部。

 1 class Solution {
 2     public void flatten(TreeNode root) { 
 3         flattenBT(root);
 4     }
 5 
 6     TreeNode flattenBT(TreeNode root) {
 7         if(root == null) return null;
 8         TreeNode leftTail = flattenBT(root.left);
 9         TreeNode rightTail = flattenBT(root.right);
10         if(root.left != null) {
11             TreeNode temp = root.right;
12             root.right = root.left;
13             root.left = null;
14             leftTail.right = temp;
15         }
16         
17         if(rightTail != null) return rightTail;
18         if(leftTail != null) return leftTail;
19         return root;
20     }
21 }

需注意几个细节
ln 10:只有当左子树存在时才将它插入右子树中
ln 17-19:返回尾部元素时,需要特殊处理 (1) 有右子树的情况,(2) 无右子树但有左子树的情况,(3)左右子树均不存在的情况。

Reference:

http://bangbingsyb.blogspot.com/2014/11/leetcode-flatten-binary-tree-to-linked.html

posted @ 2016-07-01 02:31  北叶青藤  阅读(269)  评论(0编辑  收藏  举报