Python Solution O(1) and O(n) memory.
\nclass Solution:\n    def connect(self, root: \'Node\') -> \'Node\':\n        # edge case check\n        if not root:\n            return None\n        \n     
```\nclass Solution:\n    def connect(self, root: \'Node\') -> \'Node\':\n        # edge case check\n        if not root:\n            return None\n        \n        # initialize the queue with root node (for level order traversal)\n        queue = collections.deque([root])\n        \n        # start the traversal\n        while queue:\n            size = len(queue) # get number of nodes on the current level\n            for i in range(size):\n                node = queue.popleft() # pop the node\n                \n                # An important check so that we do not wire the node to the node on the next level.\n                if i < size-1:\n                    node.next = queue[0] # because the right node of the popped node would be the next in the queue. \n                    \n                if node.left:\n                    queue.append(node.left) \n                if node.right:\n                    queue.append(node.right)           \n                \n        return root\n```\n\nO(1) Memory solution:\n```\nclass Solution:\n    def connect(self, root: \'Node\') -> \'Node\':\n        # edge case check\n        if not root:\n            return None\n        \n        node = root # create a pointer to the root node\n        \n        # iterate only until we have a new level (because the connections for Nth level are done when we are at N-1th level)\n        while node.left:\n            head = node\n            while head:\n                head.left.next = head.right\n                if head.next:\n                    head.right.next = head.next.left\n                    \n                head = head.next\n                \n            node = node.left\n\n        return root\n```
['Breadth-First Search', 'Queue', 'Python', 'Python3']