Populating Next Right Pointers in Each Node II
Follow up for problem "Populating Next Right Pointers in Each Node".
What if the given tree could be any binary tree? Would your previous solution still work?
Note:
You may only use constant extra space.
For example,
Given the following binary tree,
1
/ \
2 3
/ \ \
4 5 7
After calling your function, the tree should look like:
1 -> NULL
/ \
2 -> 3 -> NULL
/ \ \
4-> 5 -> 7 -> NULL
SOLUTION 1
本題還是可以用Level Traversal 輕松解出,連代碼都可以跟上一個題目一模一樣。Populating Next Right Pointers in Each Node Total
但是不符合空間復雜度的要求:constant extra space.
時間復雜度: O(N)

1 /** 2 * Definition for binary tree with next pointer. 3 * public class TreeLinkNode { 4 * int val; 5 * TreeLinkNode left, right, next; 6 * TreeLinkNode(int x) { val = x; } 7 * } 8 */ 9 public class Solution { 10 public void connect(TreeLinkNode root) { 11 if (root == null) { 12 return; 13 } 14 15 TreeLinkNode dummy = new TreeLinkNode(0); 16 Queue<TreeLinkNode> q = new LinkedList<TreeLinkNode>(); 17 18 q.offer(root); 19 q.offer(dummy); 20 21 while(!q.isEmpty()) { 22 TreeLinkNode cur = q.poll(); 23 if (cur == dummy) { 24 if (!q.isEmpty()) { 25 q.offer(dummy); 26 } 27 continue; 28 } 29 30 if (q.peek() == dummy) { 31 cur.next = null; 32 } else { 33 cur.next = q.peek(); 34 } 35 36 if (cur.left != null) { 37 q.offer(cur.left); 38 } 39 40 if (cur.right != null) { 41 q.offer(cur.right); 42 } 43 } 44 45 } 46 }
SOLUTION 2
我們可以用遞歸解出。注意從右往左加next。否則的話 右邊未建立,左邊你沒找不到next. Space Complexity:
時間復雜度: O(N)

1 public void connect(TreeLinkNode root) { 2 if (root == null) { 3 return; 4 } 5 6 TreeLinkNode cur = root.next; 7 TreeLinkNode next = null; 8 // this is very important. should exit after found the next. 9 while (cur != null && next == null) { 10 if (cur.left != null) { 11 next = cur.left; 12 } else if (cur.right != null) { 13 next = cur.right; 14 } else { 15 cur = cur.next; 16 } 17 } 18 19 if (root.right != null) { 20 root.right.next = next; 21 next = root.right; 22 } 23 24 if (root.left != null) { 25 root.left.next = next; 26 } 27 28 // The order is very important. We should deal with right first! 29 connect(root.right); 30 connect(root.left); 31 }
2014.1229 redo:
但現在leetcode加強數據了,不管怎么優化,遞歸的版本再也不能通過,都TLE

1 // SOLUTION 2: REC 2 public void connect(TreeLinkNode root) { 3 if (root == null) { 4 return; 5 } 6 7 TreeLinkNode dummy = new TreeLinkNode(0); 8 TreeLinkNode pre = dummy; 9 10 if (root.left != null) { 11 pre.next = root.left; 12 pre = root.left; 13 } 14 15 if (root.right != null) { 16 pre.right = root.right; 17 pre = root.right; 18 } 19 20 if (root.left == null && root.right == null) { 21 return; 22 } 23 24 // Try to find the next node; 25 TreeLinkNode cur = root.next; 26 TreeLinkNode next = null; 27 while (cur != null) { 28 if (cur.left != null) { 29 next = cur.left; 30 break; 31 } else if (cur.right != null) { 32 next = cur.right; 33 break; 34 } else { 35 cur = cur.next; 36 } 37 } 38 39 pre.next = next; 40 41 if (root.right != null && (root.right.left != null || root.right.right != null)) { 42 connect(root.right); 43 } 44 45 if (root.left != null && (root.left.left != null || root.left.right != null)) { 46 connect(root.left); 47 } 48 49 }
SOLUTION 3
我們可以用Iterator 直接解出。並且不開辟額外的空間,也就是說空間復雜度是 O(1)
時間復雜度: O(N)
感謝 http://www.geeksforgeeks.org/connect-nodes-at-same-level-with-o1-extra-space/ 的作者

1 /* 2 Solution 3: iterator with O(1) space. 3 */ 4 public void connect(TreeLinkNode root) { 5 if (root == null) { 6 return; 7 } 8 9 connIterator(root); 10 } 11 12 /* 13 This is a iterator version. 14 */ 15 public void connIterator(TreeLinkNode root) { 16 TreeLinkNode leftEnd = root; 17 while (leftEnd != null) { 18 TreeLinkNode p = leftEnd; 19 20 // Connect all the nodes in the next level together. 21 while (p != null) { 22 23 // find the 24 TreeLinkNode next = findLeftEnd(p.next); 25 26 if (p.right != null) { 27 p.right.next = next; 28 next = p.right; 29 } 30 31 if (p.left != null) { 32 p.left.next = next; 33 } 34 35 // continue to deal with the next point. 36 p = p.next; 37 } 38 39 // Find the left end of the NEXT LEVEL. 40 leftEnd = findLeftEnd(leftEnd); 41 } 42 43 } 44 45 // Find out the left end of the next level of Root TreeNode. 46 public TreeLinkNode findLeftEnd(TreeLinkNode root) { 47 while (root != null) { 48 if (root.left != null) { 49 return root.left; 50 } 51 52 if (root.right != null) { 53 return root.right; 54 } 55 56 root = root.next; 57 } 58 59 return null; 60 }
SOLUTION 4 (2014.1229):
在sol3基礎上改進,引入dummynode,我們就不需要先找到最左邊的點了。空間復雜度是 O(1)時間復雜度: O(N)

1 // SOLUTION 1: Iteration 2 public void connect1(TreeLinkNode root) { 3 if (root == null) { 4 return; 5 } 6 7 TreeLinkNode leftEnd = root; 8 9 // Bug 1: don't need " && leftEnd.left != null" 10 while (leftEnd != null) { 11 TreeLinkNode cur = leftEnd; 12 13 TreeLinkNode dummy = new TreeLinkNode(0); 14 TreeLinkNode pre = dummy; 15 while (cur != null) { 16 if (cur.left != null) { 17 pre.next = cur.left; 18 pre = cur.left; 19 } 20 21 if (cur.right != null) { 22 pre.next = cur.right; 23 pre = cur.right; 24 } 25 26 cur = cur.next; 27 } 28 leftEnd = dummy.next; 29 } 30 }
CODE ON GITHUB:
https://github.com/yuzhangcmu/LeetCode_algorithm/blob/master/tree/Connect2_2014_1229.java