Leetcode 116: Populating Next Right Pointers in Each Node
You are given a perfect binary tree where every parent node has two children and all leaves are at the same level. Your task is to populate the ’next’ pointer of each node to point to its next right node. If no such node exists, set the ’next’ pointer to NULL. Initially, all ’next’ pointers are set to NULL.
Problem
Approach
Steps
Complexity
Input: The input consists of the root of a perfect binary tree. The binary tree is represented by a node structure, where each node has a 'val', 'left', 'right', and 'next' pointer.
Example: Input: root = [10, 5, 15, 3, 7, 12, 20]
Constraints:
• The binary tree has between 0 and 2^12 - 1 nodes.
• Node values are between -1000 and 1000.
Output: The output should return the root of the tree, where each node's 'next' pointer is set to its next right node, or NULL if no next node exists.
Example: Output: [10,#,5,15,#,3,7,12,20,#]
Constraints:
• The next pointer of each node should point to the next right node, or NULL if no such node exists.
Goal: The goal is to populate the 'next' pointers for each node, connecting nodes at the same level to each other.
Steps:
• Use a level-order traversal (breadth-first search) of the tree to connect each node to the node on its right.
• For each level, connect nodes to their adjacent nodes and reset the next pointers for the next level.
• Ensure that after the last node of each level, the next pointer is set to NULL.
Goal: The tree will be a perfect binary tree with nodes between 0 and 2^12 - 1 in total. Node values will be between -1000 and 1000.
Steps:
• The number of nodes in the tree is between 0 and 2^12 - 1.
• Node values are in the range [-1000, 1000].
Assumptions:
• The tree is guaranteed to be a perfect binary tree.
• Input: Input: root = [10, 5, 15, 3, 7, 12, 20]
• Explanation: In the tree, each node's next pointer should connect it to the node to its immediate right, such as node 5's next pointer pointing to node 15, node 3's next pointer pointing to node 7, and so on. After processing, the tree should look like: [10, #, 5, 15, #, 3, 7, 12, 20, #].
• Input: Input: root = []
• Explanation: If the input tree is empty (root is NULL), the output should also be an empty tree.
Approach: To solve this problem, we can use a level-order traversal (BFS) approach. We traverse the tree level by level, connecting each node to its adjacent right node, and ensure that each level's last node points to NULL.
Observations:
• We need to connect nodes at the same level, which makes level-order traversal an appropriate choice.
• This problem can be solved using BFS without requiring additional space, as long as we adjust the pointers in-place.
Steps:
• Initialize a queue and add the root node.
• For each level, process all nodes and connect each node to the next one in the same level using the 'next' pointer.
• Ensure the last node's 'next' pointer is set to NULL.
• After processing each level, move to the next level in the tree.
Empty Inputs:
• If the input is an empty tree (root is NULL), the output should also be an empty tree.
Large Inputs:
• For large perfect binary trees, the solution should efficiently handle up to 2^12 - 1 nodes.
Special Values:
• Handle trees where the root has no children (i.e., a single node).
Constraints:
• The tree can have up to 2^12 - 1 nodes.
Node* connect(Node* root) {
if(!root) return root;
queue<Node*> q;
q.push(root);
Node* nextptr = NULL;
while(!q.empty()) {
int sz = q.size();
nextptr = NULL;
while(sz--) {
Node* tmp = q.front();
q.pop();
tmp->next = nextptr;
nextptr = tmp;
if(tmp->right) q.push(tmp->right),
q.push(tmp->left);
}
}
return root;
}
1 : Function Declaration
Node* connect(Node* root) {
Declare the function to connect all nodes at the same level in the tree.
2 : Base Case
if(!root) return root;
Handle the base case where the tree is empty.
3 : Queue Initialization
queue<Node*> q;
Initialize a queue to facilitate level-order traversal.
4 : Queue Operation
q.push(root);
Push the root node onto the queue to start the traversal.
5 : Pointer Initialization
Node* nextptr = NULL;
Initialize a pointer to track the next node at the same level.
6 : While Loop
while(!q.empty()) {
Iterate as long as there are nodes in the queue.
7 : Level Size
int sz = q.size();
Get the number of nodes at the current level.
8 : Reset Pointer
nextptr = NULL;
Reset the `next` pointer for the current level.
9 : For Each Level
while(sz--) {
Iterate over all nodes at the current level.
10 : Queue Front
Node* tmp = q.front();
Retrieve the front node from the queue.
11 : Queue Operation
q.pop();
Remove the front node from the queue.
12 : Pointer Assignment
tmp->next = nextptr;
Assign the `next` pointer of the current node.
13 : Update Pointer
nextptr = tmp;
Update the `next` pointer to the current node.
14 : Child Nodes Check
if(tmp->right) q.push(tmp->right),
If the right child exists, push it onto the queue.
15 : Child Nodes Check
q.push(tmp->left);
If the left child exists, push it onto the queue.
16 : Return Statement
return root;
Return the modified root node.
Best Case: O(n)
Average Case: O(n)
Worst Case: O(n)
Description: In all cases, the time complexity is O(n), where n is the number of nodes in the tree, as each node is processed once.
Best Case: O(n)
Worst Case: O(n)
Description: The space complexity is O(n) due to the queue used for level-order traversal. In the worst case, the queue can store all nodes at the current level.
LeetCode Solutions Library / DSA Sheets / Course Catalog |
---|
comments powered by Disqus