Yan Sun M.S. Machine Learning and Data Science, ECE @ UCSD

[Leetcode] Populating Next Right Pointers

2018-10-07

[Leetcode] Populating Next Right Pointers.

1. Intro

For a binary tree, in addition to left child and right child value. There are LeetCode problems asking about extra relationship among the nodes in the tree, including 116. Populating Next Right Pointers in Each Node and 117. Populating Next Right Pointers in Each Node II. These problems ask you to make the corresponded connection for all the nodes in the tree.

2. Populate Next Right Pointers

Given a binary tree like:

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:

1. You may only use constant extra space.
2. Recursive approach is fine, implicit stack space does not count as extra space for this problem.
3. 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

For this problem, we need a plan to go through the whole tree and make the correct next node connection for all nodes.

# Definition for binary tree with next pointer.
# class TreeLinkNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
#         self.next = None

class Solution:
    # @param root, a tree link node
    # @return nothing
    def connect(self, root):
        if not root: return
        pre = root
        while root.left:
            root.left.next = root.right
            if root.next:
                root.right.next = root.next.left
                root = root.next
            else:
                root = pre.left
                pre = root

As for each level, we store the very left node as pre, then go to deal with the nodes in this level one by one. Specifically, we need to make node.left.next = node.right. This problem assumes that the input binary tree is perfect so we do not need to care whether node.right is None or not. Then we need to check whether node.next exists or not.

If it exist, make node.right.next = node.next.left firstly and then go to the next node by node = node.next.

If node.next does not exist, it means that all nodes in this level have been visited and we need to go to the next level. Previously, we saved the very left node as pre. At this point, we can go to the next level by node = pre.left. What’s more, do not forget to save the very left node as pre again.

When node.left is empty, it means that the whole process completed.

3. Populate Next Right Pointers II

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:

1. You may only use constant extra space.
2. Recursive approach is fine, implicit stack space does not count as extra space for this problem.

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

Different from last question, it is possible that the input binary tree is not perfect, which means that we need to change the plan to go through the nodes on each level.

# Definition for binary tree with next pointer.
# class TreeLinkNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
#         self.next = None

class Solution:
    # @param root, a tree link node
    # @return nothing
    def connect(self, node):
        dummy = tail = TreeLinkNode(0)
        while node:
            tail.next = node.left
            if tail.next:
                tail = tail.next
            tail.next = node.right
            if tail.next:
                tail = tail.next
            node = node.next
            if not node:
                tail = dummy
                node = dummy.next

For each level, we initialize a dummy node and assume that the dummy node locates at the very left of each level. Then try to connect the nodes in this level by tail.next = node.left and tail.next = node.right. Between these operations we also need to check whether the child nodes exist or not via tail = tail.next if tail.next.

After going thorugh the left and right child nodes, we need to go to next node by node = node.next, if node is None at this time, it means that it is time to go to the next level. Previously, we store the original location of tail as dummy and the operation tail.next = node.left also makes dummy.next = node.left, so now we can go to next level by node = dummy.next since it is equal to node = dummy.next = node.left.

When node is empty, it means that the populating process completed and we do not need to go to the next level.


Similar Posts

Comments