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.
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