Постановка задачи
Нам дано идеальное бинарное дерево, в котором все листья находятся на одном уровне, а у каждого родителя есть два потомка. Бинарное дерево имеет следующее определение:
struct Node {
int val;
Node *left;
Node *right;
Node *next;
}
Заполните каждый следующий указатель, чтобы он указывал на его следующий правый узел. Если нет следующего правого узла, следующий указатель должен быть установлен в NULL.
Изначально все следующие указатели установлены в NULL.
Постановка задачи взята с: https://leetcode.com/problems/populating-next-right-pointers-in-each-node
Пример 1:
Input: root = [1, 2, 3, 4, 5, 6, 7]
Output: [1, #, 2, 3, #, 4, 5, 6, 7, #]
Explanation: Given the above perfect binary tree (Figure A), our 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.
Пример 2:
Input: root = []
Output: []
Ограничения:
- The number of nodes in the tree is in the range [0, 212 - 1].
- -1000 <= Node.val <= 1000
Последующие действия:
- We may only use constant extra space.
- The recursive approach is fine. We may assume implicit stack space does not count as extra space for this problem.
Объяснение
Если мы видим постановку задачи, дерево является идеальным бинарным деревом. Мы видим в примере, что следующий правый указатель для каждого узла находится на одном уровне. Мы можем выполнить обход по порядку уровней (согласно этому сообщению в блоге) и обновить следующий правый указатель для каждого узла.
Проверим алгоритм.
- if root == NULL
- return root
- initialize queue<Node*> q
- q.push(root)
- initialize Node* node
initialize i, size
- loop while !q.empty()
- set size = q.size()
- loop for i = 0; i < size; i++
- set node = q.front()
- if node->left
- q.push(node->left)
- if node->right
- q.push(node->right)
- q.pop()
- if i < size - 1
- node->next = q.front()
- return root
С++ решение
class Solution {
public:
Node* connect(Node* root) {
if(root == NULL)
return root;
queue<Node*> q;
q.push(root);
Node* node;
int i, size;
while(!q.empty()){
size = q.size();
for(i = 0; i < size; i++){
node = q.front();
if(node->left)
q.push(node->left);
if(node->right)
q.push(node->right);
q.pop();
if(i < size - 1){
node->next = q.front();
}
}
}
return root;
}
};
Голанг решение
func connect(root *Node) *Node {
if root == nil {
return root
}
queue := []*Node{root}
for len(queue) != 0 {
tmp := []int{}
size := len(queue)
for i := 0; i < size; i++ {
node := queue[0]
if queue[0] != nil {
tmp = append(tmp, queue[0].Val)
queue = append(queue, queue[0].Left)
queue = append(queue, queue[0].Right)
}
queue = queue[1:]
if i < size - 1 && queue[0] != nil {
node.Next = queue[0]
}
}
}
return root
}
Javascript-решение
var connect = function(root) {
let queue = [];
if(root)
queue.push(root);
while(queue.length > 0) {
tmp = [];
let len = queue.length;
for (let i = 0; i < len; i++) {
let node = queue.shift();
tmp.push(node.val);
if(node.left) {
queue.push(node.left);
}
if(node.right) {
queue.push(node.right);
}
if( i < len - 1 ) {
node.next = queue[0];
}
}
}
return root;
};
Давайте проверим наш алгоритм, чтобы увидеть, как работает решение.
Input: root = [1, 2, 3, 4, 5, 6, 7]
Step 1: vector<vector<int>> result
int size, i
Step 2: queue<Node*> q
q.push(root)
q = [1]
Step 3: Node* node
int i, size
Step 4: loop while !q.empty()
q = [1]
q.empty() = false
!false = true
vector<int> tmp
size = q.size()
= 1
for(i = 0; i < 1; i++)
- 0 < 1
- true
node = q.front()
node = 1
if node->left
- node->left = 2
- q.push(node->left)
- q = [1, 2]
if node->right
- node->right = 3
- q.push(node->right)
- q = [1, 2, 3]
q.pop()
q = [2, 3]
if i < size - 1
- 0 < 1 - 1
- 0 < 0
- false
1
/ \
/ \
2 3
/ \ / \
/ \ / \
4 5 6 7
Step 5: loop while !q.empty()
q = [2, 3]
q.empty() = false
!false = true
vector<int> tmp
size = q.size()
= 2
for(i = 0; i < 2; i++)
- 0 < 2
- true
node = q.front()
node = 2
if node->left
- node->left = 4
- q.push(node->left)
- q = [2, 3, 4]
if node->right
- node->right = 5
- q.push(node->right)
- q = [2, 3, 4, 5]
q.pop()
q = [3, 4, 5]
if i < size - 1
- 0 < 2 - 1
- 0 < 1
- true
- node.next = q.front()
node = 2
q.front = 3
1
/ \
/ \
2-------3
/ \ / \
/ \ / \
4 5 6 7
i++
i = 1
for(i < 2)
- 1 < 2
- true
node = q.front()
node = 3
if node->left
- node->left = 6
- q.push(node->left)
- q = [3, 4, 5, 6]
if node->right
- node->right = 7
- q.push(node->right)
- q = [3, 4, 5, 6, 7]
q.pop()
q = [4, 5, 6, 7]
if i < size - 1
- 1 < 2 - 1
- 1 < 1
- false
1
/ \
/ \
2-------3
/ \ / \
/ \ / \
4 5 6 7
for(i < 2)
- 2 < 2
- false
Step 6: loop while !q.empty()
q = [4, 5, 6, 7]
q.empty() = false
!false = true
vector<int> tmp
size = q.size()
= 4
for(i = 0; i < 4; i++)
- 0 < 4
- true
node = q.front()
node = 4
if node->left
node->left is nil so false
if node->right
node->right is nil so false
q.pop()
q = [5, 6, 7]
if i < size - 1
- 0 < 4 - 1
- 0 < 3
- true
- node->next = q.front()
node = 4
q.front() = 5
1
/ \
/ \
2-------3
/ \ / \
/ \ / \
4-----5 6 7
i++
i = 1
for(i < 4)
- 1 < 4
- true
node = q.front()
node = 5
if node->left
node->left is nil so false
if node->right
node->right is nil so false
q.pop()
q = [6, 7]
if i < size - 1
- 1 < 4 - 1
- 1 < 3
- true
- node->next = q.front()
node = 5
q.front() = 6
1
/ \
/ \
2-------3
/ \ / \
/ \ / \
4-----5-6 7
i++
i = 2
for(i < 4)
- 2 < 4
- true
node = q.front()
node = 6
if node->left
node->left is nil so false
if node->right
node->right is nil so false
q.pop()
q = [7]
if i < size - 1
- 2 < 4 - 1
- 2 < 3
- true
- node->next = q.front()
node = 6
q.front() = 7
1
/ \
/ \
2-------3
/ \ / \
/ \ / \
4-----5-6-----7
i++
i = 3
for(i < 4)
- 3 < 4
- true
node = q.front()
node = 7
if node->left
node->left is nil so false
if node->right
node->right is nil so false
q.pop()
q = []
if i < size - 1
- 3 < 4 - 1
- 3 < 3
- false
1
/ \
/ \
2-------3
/ \ / \
/ \ / \
4-----5-6-----7
i++
i = 4
for(i < 4)
- 4 < 4
- false
Step 7: return root
So we return the answer as
1
/ \
/ \
2-------3
/ \ / \
/ \ / \
4-----5-6-----7
[1, #, 2, 3, #, 4, 5, 6, 7, #]
Первоначально опубликовано на https://alkeshghorpade.me.