vault backup: 2022-07-17 11:13:12
This commit is contained in:
parent
ec7733cae6
commit
b66312368e
|
@ -64,6 +64,13 @@ Initially, all next pointers are set to `NULL`.
|
|||
|
||||
> [!summary]
|
||||
> This is a #BFS problem, and cam be optimized
|
||||
> It relies on the fact that it is perfect binary tree.
|
||||
> The core part for optimization is utilizing ptr->next
|
||||
|
||||
Using ptr->next in DFS and iteration enable us to traverse
|
||||
between branches like in BFS
|
||||
|
||||
![[DFS with links.png]]
|
||||
|
||||
##### BFS way of doing this, O(n)time, O(n + 1)space
|
||||
|
||||
|
@ -71,19 +78,33 @@ simple BFS, for each level, connect the node to the next.
|
|||
|
||||
Remember to get the for loop right.
|
||||
|
||||
##### BFS-like iteration, two pointers
|
||||
##### BFS-like iteration, two pointers, O(n)time, O(n + 1)space
|
||||
|
||||
We utilize the ->next property to link ptr->left->right->next to ptr->right->left
|
||||
We utilize the ->next property to link
|
||||
ptr->left->right->next to ptr->right->left
|
||||
|
||||
![[Leetcode Populating next right ptr-2.png]]
|
||||
|
||||
##### Also can be done with DFS
|
||||
We can't use ptr->left->right->next = ptr->right->left,
|
||||
since this is only one level, and doesn't work on two levels:
|
||||
|
||||
![[Leetcode Populating next right ptr-1.png]]
|
||||
|
||||
##### Also can be done with DFS O(n), O(n)
|
||||
|
||||
We recursively fill next pointers the level below current.
|
||||
|
||||
Base case:
|
||||
- Root->left is empty, which means this is the leaf level, quit.
|
||||
|
||||
Pseudo-code:
|
||||
1. Check for base case
|
||||
1. link root->left and root->right
|
||||
1. link root->right and root->next->left (if root->next is valid.)
|
||||
|
||||
### Solution
|
||||
|
||||
|
||||
BFS unoptimized:
|
||||
DFS:
|
||||
```cpp
|
||||
/*
|
||||
// Definition for a Node.
|
||||
|
@ -104,40 +125,93 @@ public:
|
|||
*/
|
||||
|
||||
class Solution {
|
||||
public:
|
||||
Node* connect(Node* root) {
|
||||
// BFS.
|
||||
// Can we do it with DFS?
|
||||
queue<Node*> todo;
|
||||
|
||||
if (root && root->left && root->right) {
|
||||
todo.push(root->left);
|
||||
todo.push(root->right);
|
||||
}
|
||||
|
||||
Node *ptr, *nextPtr;
|
||||
|
||||
while (!todo.empty()) {
|
||||
nextPtr = todo.front();
|
||||
todo.pop();
|
||||
for (size_t i = 0, size = todo.size(); i < size; i++) {
|
||||
ptr = nextPtr;
|
||||
nextPtr = todo.front();
|
||||
todo.pop();
|
||||
|
||||
ptr->next = nextPtr;
|
||||
if (ptr->left) {
|
||||
todo.push(ptr->left);
|
||||
todo.push(ptr->right);
|
||||
}
|
||||
}
|
||||
if (nextPtr->left) {
|
||||
todo.push(nextPtr->left);
|
||||
todo.push(nextPtr->right);
|
||||
}
|
||||
}
|
||||
|
||||
return root;
|
||||
void conn(Node *root) {
|
||||
// preorder DFS, here we go!
|
||||
// It assumes at least one level, which doesn't include []
|
||||
if (root->left) {
|
||||
root->left->next = root->right;
|
||||
if (root->next) {
|
||||
root->right->next = root->next->left;
|
||||
}
|
||||
conn(root->left);
|
||||
conn(root->right);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
Node *connect(Node *root) {
|
||||
if (root) {
|
||||
conn(root);
|
||||
}
|
||||
return root;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
Iterative, O(n)time O(1)space
|
||||
```cpp
|
||||
class Solution {
|
||||
public:
|
||||
Node *connect(Node *root) {
|
||||
// iteration
|
||||
Node *ptr = root;
|
||||
Node *nextPtr = nullptr;
|
||||
while (ptr && ptr->left) {
|
||||
ptr->left->next = ptr->right;
|
||||
if (!nextPtr) {
|
||||
nextPtr = ptr->left;
|
||||
}
|
||||
if (!ptr->next) {
|
||||
ptr = nextPtr;
|
||||
nextPtr = nullptr;
|
||||
} else {
|
||||
ptr->right->next = ptr->next->left;
|
||||
ptr = ptr->next;
|
||||
}
|
||||
}
|
||||
return root;
|
||||
}
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
BFS unoptimized:
|
||||
```cpp
|
||||
class Solution {
|
||||
public:
|
||||
Node *connect(Node *root) {
|
||||
// BFS.
|
||||
// Can we do it with DFS?
|
||||
queue<Node *> todo;
|
||||
|
||||
if (root && root->left && root->right) {
|
||||
todo.push(root->left);
|
||||
todo.push(root->right);
|
||||
}
|
||||
|
||||
Node *ptr, *nextPtr;
|
||||
|
||||
while (!todo.empty()) {
|
||||
nextPtr = todo.front();
|
||||
todo.pop();
|
||||
for (size_t i = 0, size = todo.size(); i < size; i++) {
|
||||
ptr = nextPtr;
|
||||
nextPtr = todo.front();
|
||||
todo.pop();
|
||||
|
||||
ptr->next = nextPtr;
|
||||
if (ptr->left) {
|
||||
todo.push(ptr->left);
|
||||
todo.push(ptr->right);
|
||||
}
|
||||
}
|
||||
if (nextPtr->left) {
|
||||
todo.push(nextPtr->left);
|
||||
todo.push(nextPtr->right);
|
||||
}
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
};
|
||||
```
|
BIN
_files/DFS with links.png
Normal file
BIN
_files/DFS with links.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 66 KiB |
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
Loading…
Reference in a new issue