Given a binary tree
struct TreeLinkNode { TreeLinkNode *left; TreeLinkNode *right; TreeLinkNode *next; }
Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be set to NULL
.
Initially, all next pointers are set to NULL
.
Note:
- You may only use constant extra space.
- Recursive approach is fine, implicit stack space does not count as extra space for this problem.
- You may assume that it is a perfect binary tree (ie, all leaves are at the same level, and every parent has two children).
Example:
Given the following perfect binary tree, 1 / \ 2 3 / \ / \ 4 5 6 7 After calling your function, the tree should look like: 1 -> NULL / \ 2 -> 3 -> NULL / \ / \ 4->5->6->7 -> NULL
这里递归不算extra space,那么先试试看递归解法。
对于第一层只有root(如果其存在),那么需要看它的左孩子是否存在。如果存在,那么它的next一定等于root的右孩子,不论右孩子存不存在。而对于右孩子,仅仅对于第一层root来说,这一步不用做任何事,只不过如果root右孩子存在,那么此时它已经被连接到root左孩子的next上,而且它本身的next初始为null。这样继续递归调用下一层的节点时候,同样的左孩子如果存在,其next连到右孩子。而这时候要判断此时根节点的next是否为null。如果不为null,相当于此时根节点存在同层的兄弟节点,且这个兄弟节点已经存在当前递归节点的next域中。那么,如果这时根节点的右孩子也存在的话,它是一定等于根节点的兄弟节点的左孩子,不论其左孩子是否为空。之后递归调用每一层根节点的左右孩子即可。看上去很绕,但原理是每一次连上一个根节点的左右孩子,这样下一层时候就知道了兄弟节点是否存在,以便于继续链接根节点及其兄弟节点的孩子。
对于迭代,如果不需要常数空间复杂度的话,可以利用队列将每一层的节点存起来,之后逐个处理next域。如果要求常数复杂度,那么就需要在每一层增加一个指针node,从最左边遍历到最右边,逐个将节点连接起来。遍历的方法和递归的想法一样,还是利用上一层next已经连接起来的结果,通过父节点的next域移动到兄弟节点的子节点。
解法一,递归(Java)
/** * Definition for binary tree with next pointer. * public class TreeLinkNode { * int val; * TreeLinkNode left, right, next; * TreeLinkNode(int x) { val = x; } * } */ public class Solution { public void connect(TreeLinkNode root) { if (root == null) return; if (root.left != null) root.left.next = root.right; if (root.next != null && root.right != null) root.right.next = root.next.left; connect(root.left); connect(root.right); } }
解法二,迭代,非常数空间(Java)
/** * Definition for binary tree with next pointer. * public class TreeLinkNode { * int val; * TreeLinkNode left, right, next; * TreeLinkNode(int x) { val = x; } * } */ public class Solution { public void connect(TreeLinkNode root) { if (root == null) return; Queue<TreeLinkNode> q = new LinkedList<>(); q.add(root); while (!q.isEmpty()) { int size = q.size(); for (int i = 0; i < size; i++) { TreeLinkNode t = q.poll(); if (i < size - 1) t.next = q.peek(); if (t.left != null) q.add(t.left); if (t.right != null) q.add(t.right); } } } }
解法三,迭代,常数空间(Java)
/** * Definition for binary tree with next pointer. * public class TreeLinkNode { * int val; * TreeLinkNode left, right, next; * TreeLinkNode(int x) { val = x; } * } */ public class Solution { public void connect(TreeLinkNode root) { if (root == null) return; TreeLinkNode pre = root; while (pre.left != null) { TreeLinkNode cur = pre; while (cur != null) { cur.left.next = cur.right; if (cur.next != null) cur.right.next = cur.next.left; cur = cur.next; } pre = pre.left; } } }