MUYANG GUO / INDEX

LeetCode

LeetCode 117 Populating Next Right Pointers In Each Node II - Medium

117. Populating Next Right Pointers in Each Node II -- Medium

·4 min read·#LeetCode#Medium#Python

117. Populating Next Right Pointers In Each Node II — Medium

Open on LeetCode

Problem

  1. Populating Next Right Pointers in Each Node II -- Medium

Given a binary tree struct Node { int val; Node *left; Node *right; Node *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.

Follow up: You may only use constant extra space. Recursive approach is fine, you may assume implicit stack space does not count as extra space for this problem.

Example 1: Input: root = [1,2,3,4,5,null,7] Output: [1,#,2,3,#,4,5,7,#] Explanation: Given the above binary tree (Figure A), your function should populate each next pointer to point to its next right node, just like in Figure B. The serialized output is in level order as connected by the next pointers, with '#' signifying the end of each level.

Constraints: The number of nodes in the given tree is less than 6000. -100 <= node.val <= 100

Solution

### BFS: O(N), O(N)
# Definition for a Node.
class Node:
    def __init__(self, val: int = 0, left: 'Node' = None, right: 'Node' = None, next: 'Node' = None):
        self.val = val
        self.left = left
        self.right = right
        self.next = next
 
class Solution:
    def connect(self, root: 'Node') -> 'Node':
        if not root:
            return root
        # Initialize a queue data structure which contains
        # just the root of the tree
        Q = collections.deque([root])
        # Outer while loop which iterates over 
        # each level
        while Q:
            # Note the size of the queue
            size = len(Q)
            # Iterate over all the nodes on the current level
            for i in range(size):
                # Pop a node from the front of the queue
                node = Q.popleft()
                # This check is important. We don't want to
                # establish any wrong connections. The queue will
                # contain nodes from 2 levels at most at any
                # point in time. This check ensures we only 
                # don't establish next pointers beyond the end
                # of a level
                if i < size - 1:
                    node.next = Q[0]
                # Add the children, if any, to the back of
                # the queue
                if node.left:
                    Q.append(node.left)
                if node.right:
                    Q.append(node.right)
        # Since the tree has now been modified, return the root node
        return root
 
### O(N), O(1), 直接利用next指针来相当于level的queue,前提是用上一层的信息,修改下一层。
 
# Definition for a Node.
class Node:
    def __init__(self, val: int = 0, left: 'Node' = None, right: 'Node' = None, next: 'Node' = None):
        self.val = val
        self.left = left
        self.right = right
        self.next = next
class Solution:
    def processChild(self, childNode, prev, leftmost):
        if childNode:
            # If the "prev" pointer is alread set i.e. if we
            # already found atleast one node on the next level,
            # setup its next pointer
            if prev:
                prev.next = childNode
            else:    
                # Else it means this child node is the first node
                # we have encountered on the next level, so, we
                # set the leftmost pointer
                leftmost = childNode
            prev = childNode 
        return prev, leftmost
    
    def connect(self, root: 'Node') -> 'Node':
        
        if not root:
            return root
        # The root node is the only node on the first level
        # and hence its the leftmost node for that level
        leftmost = root
        # We have no idea about the structure of the tree,
        # so, we keep going until we do find the last level.
        # The nodes on the last level won't have any children
        while leftmost:
            # "prev" tracks the latest node on the "next" level
            # while "curr" tracks the latest node on the current
            # level.
            prev, curr = None, leftmost
            # We reset this so that we can re-assign it to the leftmost
            # node of the next level. Also, if there isn't one, this
            # would help break us out of the outermost loop.
            leftmost = None
            # Iterate on the nodes in the current level using
            # the next pointers already established.
            while curr:
                # Process both the children and update the prev
                # and leftmost pointers as necessary.
                prev, leftmost = self.processChild(curr.left, prev, leftmost)
                prev, leftmost = self.processChild(curr.right, prev, leftmost)
                # Move onto the next node.
                curr = curr.next
        return root

Comments