This commit is contained in:
krahets 2023-10-17 23:44:50 +08:00
parent de9bf5a57a
commit 64c5d13051
4 changed files with 102 additions and 43 deletions

View File

@ -237,9 +237,9 @@ comments: true
```rust title="list.rs" ```rust title="list.rs"
/* 访问元素 */ /* 访问元素 */
let num: i32 = nums[1]; // 访问索引 1 处的元素 let num: i32 = nums[1]; // 访问索引 1 处的元素
/* 更新元素 */ /* 更新元素 */
nums[1] = 0; // 将索引 1 处的元素更新为 0 nums[1] = 0; // 将索引 1 处的元素更新为 0
``` ```
=== "C" === "C"

View File

@ -99,7 +99,7 @@ comments: true
// 遍历所有选择 // 遍历所有选择
for (int i = 0; i < choices.size(); i++) { for (int i = 0; i < choices.size(); i++) {
int choice = choices[i]; int choice = choices[i];
// 剪枝:不允许重复选择元素 且 不允许重复选择相等元素 // 剪枝:不允许重复选择元素
if (!selected[i]) { if (!selected[i]) {
// 尝试:做出选择,更新状态 // 尝试:做出选择,更新状态
selected[i] = true; selected[i] = true;
@ -136,7 +136,7 @@ comments: true
// 遍历所有选择 // 遍历所有选择
for (int i = 0; i < choices.length; i++) { for (int i = 0; i < choices.length; i++) {
int choice = choices[i]; int choice = choices[i];
// 剪枝:不允许重复选择元素 且 不允许重复选择相等元素 // 剪枝:不允许重复选择元素
if (!selected[i]) { if (!selected[i]) {
// 尝试:做出选择,更新状态 // 尝试:做出选择,更新状态
selected[i] = true; selected[i] = true;
@ -171,7 +171,7 @@ comments: true
// 遍历所有选择 // 遍历所有选择
for (int i = 0; i < choices.Length; i++) { for (int i = 0; i < choices.Length; i++) {
int choice = choices[i]; int choice = choices[i];
// 剪枝:不允许重复选择元素 且 不允许重复选择相等元素 // 剪枝:不允许重复选择元素
if (!selected[i]) { if (!selected[i]) {
// 尝试:做出选择,更新状态 // 尝试:做出选择,更新状态
selected[i] = true; selected[i] = true;
@ -206,7 +206,7 @@ comments: true
// 遍历所有选择 // 遍历所有选择
for i := 0; i < len(*choices); i++ { for i := 0; i < len(*choices); i++ {
choice := (*choices)[i] choice := (*choices)[i]
// 剪枝:不允许重复选择元素 且 不允许重复选择相等元素 // 剪枝:不允许重复选择元素
if !(*selected)[i] { if !(*selected)[i] {
// 尝试:做出选择,更新状态 // 尝试:做出选择,更新状态
(*selected)[i] = true (*selected)[i] = true
@ -242,7 +242,7 @@ comments: true
} }
// 遍历所有选择 // 遍历所有选择
for (i, choice) in choices.enumerated() { for (i, choice) in choices.enumerated() {
// 剪枝:不允许重复选择元素 且 不允许重复选择相等元素 // 剪枝:不允许重复选择元素
if !selected[i] { if !selected[i] {
// 尝试:做出选择,更新状态 // 尝试:做出选择,更新状态
selected[i] = true selected[i] = true
@ -278,7 +278,7 @@ comments: true
} }
// 遍历所有选择 // 遍历所有选择
choices.forEach((choice, i) => { choices.forEach((choice, i) => {
// 剪枝:不允许重复选择元素 且 不允许重复选择相等元素 // 剪枝:不允许重复选择元素
if (!selected[i]) { if (!selected[i]) {
// 尝试:做出选择,更新状态 // 尝试:做出选择,更新状态
selected[i] = true; selected[i] = true;
@ -317,7 +317,7 @@ comments: true
} }
// 遍历所有选择 // 遍历所有选择
choices.forEach((choice, i) => { choices.forEach((choice, i) => {
// 剪枝:不允许重复选择元素 且 不允许重复选择相等元素 // 剪枝:不允许重复选择元素
if (!selected[i]) { if (!selected[i]) {
// 尝试:做出选择,更新状态 // 尝试:做出选择,更新状态
selected[i] = true; selected[i] = true;
@ -357,7 +357,7 @@ comments: true
// 遍历所有选择 // 遍历所有选择
for (int i = 0; i < choices.length; i++) { for (int i = 0; i < choices.length; i++) {
int choice = choices[i]; int choice = choices[i];
// 剪枝:不允许重复选择元素 且 不允许重复选择相等元素 // 剪枝:不允许重复选择元素
if (!selected[i]) { if (!selected[i]) {
// 尝试:做出选择,更新状态 // 尝试:做出选择,更新状态
selected[i] = true; selected[i] = true;
@ -392,7 +392,7 @@ comments: true
// 遍历所有选择 // 遍历所有选择
for i in 0..choices.len() { for i in 0..choices.len() {
let choice = choices[i]; let choice = choices[i];
// 剪枝:不允许重复选择元素 且 不允许重复选择相等元素 // 剪枝:不允许重复选择元素
if !selected[i] { if !selected[i] {
// 尝试:做出选择,更新状态 // 尝试:做出选择,更新状态
selected[i] = true; selected[i] = true;
@ -418,49 +418,47 @@ comments: true
```c title="permutations_i.c" ```c title="permutations_i.c"
/* 回溯算法:全排列 I */ /* 回溯算法:全排列 I */
void backtrack(vector *state, vector *choices, vector *selected, vector *res) { void backtrack(int *state, int stateSize, int *choices, int choicesSize, bool *selected, int **res, int *resSize) {
// 当状态长度等于元素数量时,记录解 // 当状态长度等于元素数量时,记录解
if (state->size == choices->size) { if (stateSize == choicesSize) {
vector *newState = newVector(); res[*resSize] = (int *)malloc(choicesSize * sizeof(int));
for (int i = 0; i < state->size; i++) { for (int i = 0; i < choicesSize; i++) {
vectorPushback(newState, state->data[i], sizeof(int)); res[*resSize][i] = state[i];
} }
vectorPushback(res, newState, sizeof(vector)); (*resSize)++;
return; return;
} }
// 遍历所有选择 // 遍历所有选择
for (int i = 0; i < choices->size; i++) { for (int i = 0; i < choicesSize; i++) {
int *choice = malloc(sizeof(int)); int choice = choices[i];
*choice = *((int *)(choices->data[i])); // 剪枝:不允许重复选择元素
// 剪枝:不允许重复选择元素 且 不允许重复选择相等元素 if (!selected[i]) {
bool select = *((bool *)(selected->data[i]));
if (!select) {
// 尝试:做出选择,更新状态 // 尝试:做出选择,更新状态
*((bool *)selected->data[i]) = true; selected[i] = true;
vectorPushback(state, choice, sizeof(int)); state[stateSize] = choice;
// 进行下一轮选择 // 进行下一轮选择
backtrack(state, choices, selected, res); backtrack(state, stateSize + 1, choices, choicesSize, selected, res, resSize);
// 回退:撤销选择,恢复到之前的状态 // 回退:撤销选择,恢复到之前的状态
*((bool *)selected->data[i]) = false; selected[i] = false;
vectorPopback(state);
} }
} }
} }
/* 全排列 I */ /* 全排列 I */
vector *permutationsI(vector *nums) { int **permutationsI(int *nums, int numsSize, int *returnSize) {
vector *iState = newVector(); int *state = (int *)malloc(numsSize * sizeof(int));
bool *selected = (bool *)malloc(numsSize * sizeof(bool));
int select[3] = {false, false, false}; for (int i = 0; i < numsSize; i++) {
vector *bSelected = newVector(); selected[i] = false;
for (int i = 0; i < nums->size; i++) {
vectorPushback(bSelected, &select[i], sizeof(int));
} }
int **res = (int **)malloc(MAX_SIZE * sizeof(int *));
*returnSize = 0;
vector *res = newVector(); backtrack(state, 0, nums, numsSize, selected, res, returnSize);
free(state);
free(selected);
// 前序遍历
backtrack(iState, nums, bSelected, res);
return res; return res;
} }
``` ```
@ -888,9 +886,52 @@ comments: true
=== "C" === "C"
```c title="permutations_ii.c" ```c title="permutations_ii.c"
[class]{}-[func]{backtrack} /* 回溯算法:全排列 II */
void backtrack(int *state, int stateSize, int *choices, int choicesSize, bool *selected, int **res, int *resSize) {
// 当状态长度等于元素数量时,记录解
if (stateSize == choicesSize) {
res[*resSize] = (int *)malloc(choicesSize * sizeof(int));
for (int i = 0; i < choicesSize; i++) {
res[*resSize][i] = state[i];
}
(*resSize)++;
return;
}
// 遍历所有选择
bool duplicated[MAX_SIZE] = {false};
for (int i = 0; i < choicesSize; i++) {
int choice = choices[i];
// 剪枝:不允许重复选择元素 且 不允许重复选择相等元素
if (!selected[i] && !duplicated[choice]) {
// 尝试:做出选择,更新状态
duplicated[choice] = true; // 记录选择过的元素值
selected[i] = true;
state[stateSize] = choice;
// 进行下一轮选择
backtrack(state, stateSize + 1, choices, choicesSize, selected, res, resSize);
// 回退:撤销选择,恢复到之前的状态
selected[i] = false;
}
}
}
[class]{}-[func]{permutationsII} /* 全排列 II */
int **permutationsII(int *nums, int numsSize, int *returnSize) {
int *state = (int *)malloc(numsSize * sizeof(int));
bool *selected = (bool *)malloc(numsSize * sizeof(bool));
for (int i = 0; i < numsSize; i++) {
selected[i] = false;
}
int **res = (int **)malloc(MAX_SIZE * sizeof(int *));
*returnSize = 0;
backtrack(state, 0, nums, numsSize, selected, res, returnSize);
free(state);
free(selected);
return res;
}
``` ```
=== "Zig" === "Zig"

View File

@ -404,9 +404,27 @@ comments: true
=== "C" === "C"
```c title="build_tree.c" ```c title="build_tree.c"
[class]{}-[func]{dfs} /* 构建二叉树 */
fn build_tree(preorder: &[i32], inorder: &[i32]) -> Option<Rc<RefCell<TreeNode>>> {
// 初始化哈希表,存储 inorder 元素到索引的映射
let mut inorder_map: HashMap<i32, i32> = HashMap::new();
for i in 0..inorder.len() {
inorder_map.insert(inorder[i], i as i32);
}
let root = dfs(preorder, &inorder_map, 0, 0, inorder.len() as i32 - 1);
root
}
[class]{}-[func]{buildTree} /* 构建二叉树 */
fn build_tree(preorder: &[i32], inorder: &[i32]) -> Option<Rc<RefCell<TreeNode>>> {
// 初始化哈希表,存储 inorder 元素到索引的映射
let mut inorder_map: HashMap<i32, i32> = HashMap::new();
for i in 0..inorder.len() {
inorder_map.insert(inorder[i], i as i32);
}
let root = dfs(preorder, &inorder_map, 0, 0, inorder.len() as i32 - 1);
root
}
``` ```
=== "Zig" === "Zig"

View File

@ -743,7 +743,7 @@ $$
=== "Go" === "Go"
```go title="built_in_hash.go" ```go title="built_in_hash.go"
// Go 未提供内置 hash code 函数
``` ```
=== "Swift" === "Swift"