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]
|
> [!summary]
|
||||||
> This is a #BFS problem, and cam be optimized
|
> 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
|
##### 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.
|
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
|
### Solution
|
||||||
|
|
||||||
|
DFS:
|
||||||
BFS unoptimized:
|
|
||||||
```cpp
|
```cpp
|
||||||
/*
|
/*
|
||||||
// Definition for a Node.
|
// Definition for a Node.
|
||||||
|
@ -104,40 +125,93 @@ public:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class Solution {
|
class Solution {
|
||||||
public:
|
void conn(Node *root) {
|
||||||
Node* connect(Node* root) {
|
// preorder DFS, here we go!
|
||||||
// BFS.
|
// It assumes at least one level, which doesn't include []
|
||||||
// Can we do it with DFS?
|
if (root->left) {
|
||||||
queue<Node*> todo;
|
root->left->next = root->right;
|
||||||
|
if (root->next) {
|
||||||
if (root && root->left && root->right) {
|
root->right->next = root->next->left;
|
||||||
todo.push(root->left);
|
}
|
||||||
todo.push(root->right);
|
conn(root->left);
|
||||||
}
|
conn(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;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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