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;
        }    
    }
}

 

posted on 2018-08-29 21:02  小T在学习  阅读(309)  评论(0编辑  收藏  举报