This commit is contained in:
krahets 2023-05-16 14:51:37 +08:00
parent 7f43facfd9
commit 749918677f
5 changed files with 649 additions and 52 deletions

View file

@ -63,19 +63,52 @@ comments: true
=== "Go" === "Go"
```go title="preorder_traversal_i_compact.go" ```go title="preorder_traversal_i_compact.go"
[class]{}-[func]{preOrder} /* 前序遍历:例题一 */
func preOrderI(root *TreeNode, res *[]*TreeNode) {
if root == nil {
return
}
if int(root.Val) == 7 {
// 记录解
*res = append(*res, root)
}
preOrderI(root.Left, res)
preOrderI(root.Right, res)
}
``` ```
=== "JavaScript" === "JavaScript"
```javascript title="preorder_traversal_i_compact.js" ```javascript title="preorder_traversal_i_compact.js"
[class]{}-[func]{preOrder} /* 前序遍历:例题一 */
function preOrder(root, res) {
if (root === null) {
return;
}
if (root.val === 7) {
// 记录解
res.push(root);
}
preOrder(root.left, res);
preOrder(root.right, res);
}
``` ```
=== "TypeScript" === "TypeScript"
```typescript title="preorder_traversal_i_compact.ts" ```typescript title="preorder_traversal_i_compact.ts"
[class]{}-[func]{preOrder} /* 前序遍历:例题一 */
function preOrder(root: TreeNode | null, res: TreeNode[]): void {
if (root === null) {
return;
}
if (root.val === 7) {
// 记录解
res.push(root);
}
preOrder(root.left, res);
preOrder(root.right, res);
}
``` ```
=== "C" === "C"
@ -203,19 +236,68 @@ comments: true
=== "Go" === "Go"
```go title="preorder_traversal_ii_compact.go" ```go title="preorder_traversal_ii_compact.go"
[class]{}-[func]{preOrder} /* 前序遍历:例题二 */
func preOrderII(root *TreeNode, res *[][]*TreeNode, path *[]*TreeNode) {
if root == nil {
return
}
// 尝试
*path = append(*path, root)
if int(root.Val) == 7 {
// 记录解
*res = append(*res, *path)
}
preOrderII(root.Left, res, path)
preOrderII(root.Right, res, path)
// 回退
*path = (*path)[:len(*path)-1]
}
``` ```
=== "JavaScript" === "JavaScript"
```javascript title="preorder_traversal_ii_compact.js" ```javascript title="preorder_traversal_ii_compact.js"
[class]{}-[func]{preOrder} /* 前序遍历:例题二 */
function preOrder(root, path, res) {
if (root === null) {
return;
}
// 尝试
path.push(root);
if (root.val === 7) {
// 记录解
res.push([...path]);
}
preOrder(root.left, path, res);
preOrder(root.right, path, res);
// 回退
path.pop();
}
``` ```
=== "TypeScript" === "TypeScript"
```typescript title="preorder_traversal_ii_compact.ts" ```typescript title="preorder_traversal_ii_compact.ts"
[class]{}-[func]{preOrder} /* 前序遍历:例题二 */
function preOrder(
root: TreeNode | null,
path: TreeNode[],
res: TreeNode[][]
): void {
if (root === null) {
return;
}
// 尝试
path.push(root);
if (root.val === 7) {
// 记录解
res.push([...path]);
}
preOrder(root.left, path, res);
preOrder(root.right, path, res);
// 回退
path.pop();
}
``` ```
=== "C" === "C"
@ -381,19 +463,71 @@ comments: true
=== "Go" === "Go"
```go title="preorder_traversal_iii_compact.go" ```go title="preorder_traversal_iii_compact.go"
[class]{}-[func]{preOrder} /* 前序遍历:例题三 */
func preOrderIII(root *TreeNode, res *[][]*TreeNode, path *[]*TreeNode) {
// 剪枝
if root == nil || root.Val == 3 {
return
}
// 尝试
*path = append(*path, root)
if int(root.Val) == 7 {
// 记录解
*res = append(*res, *path)
}
preOrderIII(root.Left, res, path)
preOrderIII(root.Right, res, path)
// 回退
*path = (*path)[:len(*path)-1]
}
``` ```
=== "JavaScript" === "JavaScript"
```javascript title="preorder_traversal_iii_compact.js" ```javascript title="preorder_traversal_iii_compact.js"
[class]{}-[func]{preOrder} /* 前序遍历:例题三 */
function preOrder(root, path, res) {
// 剪枝
if (root === null || root.val === 3) {
return;
}
// 尝试
path.push(root);
if (root.val === 7) {
// 记录解
res.push([...path]);
}
preOrder(root.left, path, res);
preOrder(root.right, path, res);
// 回退
path.pop();
}
``` ```
=== "TypeScript" === "TypeScript"
```typescript title="preorder_traversal_iii_compact.ts" ```typescript title="preorder_traversal_iii_compact.ts"
[class]{}-[func]{preOrder} /* 前序遍历:例题三 */
function preOrder(
root: TreeNode | null,
path: TreeNode[],
res: TreeNode[][]
): void {
// 剪枝
if (root === null || root.val === 3) {
return;
}
// 尝试
path.push(root);
if (root.val === 7) {
// 记录解
res.push([...path]);
}
preOrder(root.left, path, res);
preOrder(root.right, path, res);
// 回退
path.pop();
}
``` ```
=== "C" === "C"
@ -858,15 +992,30 @@ comments: true
=== "Go" === "Go"
```go title="preorder_traversal_iii_template.go" ```go title="preorder_traversal_iii_template.go"
[class]{}-[func]{isSolution} /* 判断当前状态是否为解 */
func isSolution(state *[]*TreeNode) bool {
return len(*state) != 0 && (*state)[len(*state)-1].Val == 7
}
[class]{}-[func]{recordSolution} /* 记录解 */
func recordSolution(state *[]*TreeNode, res *[][]*TreeNode) {
*res = append(*res, *state)
}
[class]{}-[func]{isValid} /* 判断在当前状态下,该选择是否合法 */
func isValid(state *[]*TreeNode, choice *TreeNode) bool {
return choice != nil && choice.Val != 3
}
[class]{}-[func]{makeChoice} /* 更新状态 */
func makeChoice(state *[]*TreeNode, choice *TreeNode) {
*state = append(*state, choice)
}
[class]{}-[func]{undoChoice} /* 恢复状态 */
func undoChoice(state *[]*TreeNode, choice *TreeNode) {
*state = (*state)[:len(*state)-1]
}
[class]{}-[func]{backtrack} [class]{}-[func]{backtrack}
``` ```
@ -874,33 +1023,107 @@ comments: true
=== "JavaScript" === "JavaScript"
```javascript title="preorder_traversal_iii_template.js" ```javascript title="preorder_traversal_iii_template.js"
[class]{}-[func]{isSolution} /* 判断当前状态是否为解 */
function isSolution(state) {
return state && state[state.length - 1]?.val === 7;
}
[class]{}-[func]{recordSolution} /* 记录解 */
function recordSolution(state, res) {
res.push([...state]);
}
[class]{}-[func]{isValid} /* 判断在当前状态下,该选择是否合法 */
function isValid(state, choice) {
return choice !== null && choice.val !== 3;
}
[class]{}-[func]{makeChoice} /* 更新状态 */
function makeChoice(state, choice) {
state.push(choice);
}
[class]{}-[func]{undoChoice} /* 恢复状态 */
function undoChoice(state) {
state.pop();
}
[class]{}-[func]{backtrack} /* 回溯算法:例题三 */
function backtrack(state, choices, res) {
// 检查是否为解
if (isSolution(state)) {
// 记录解
recordSolution(state, res);
return;
}
// 遍历所有选择
for (const choice of choices) {
// 剪枝:检查选择是否合法
if (isValid(state, choice)) {
// 尝试:做出选择,更新状态
makeChoice(state, choice);
// 进行下一轮选择
backtrack(state, [choice.left, choice.right], res);
// 回退:撤销选择,恢复到之前的状态
undoChoice(state);
}
}
}
``` ```
=== "TypeScript" === "TypeScript"
```typescript title="preorder_traversal_iii_template.ts" ```typescript title="preorder_traversal_iii_template.ts"
[class]{}-[func]{isSolution} /* 判断当前状态是否为解 */
function isSolution(state: TreeNode[]): boolean {
return state && state[state.length - 1]?.val === 7;
}
[class]{}-[func]{recordSolution} /* 记录解 */
function recordSolution(state: TreeNode[], res: TreeNode[][]): void {
res.push([...state]);
}
[class]{}-[func]{isValid} /* 判断在当前状态下,该选择是否合法 */
function isValid(state: TreeNode[], choice: TreeNode): boolean {
return choice !== null && choice.val !== 3;
}
[class]{}-[func]{makeChoice} /* 更新状态 */
function makeChoice(state: TreeNode[], choice: TreeNode): void {
state.push(choice);
}
[class]{}-[func]{undoChoice} /* 恢复状态 */
function undoChoice(state: TreeNode[]): void {
state.pop();
}
[class]{}-[func]{backtrack} /* 回溯算法:例题三 */
function backtrack(
state: TreeNode[],
choices: TreeNode[],
res: TreeNode[][]
): void {
// 检查是否为解
if (isSolution(state)) {
// 记录解
recordSolution(state, res);
return;
}
// 遍历所有选择
for (const choice of choices) {
// 剪枝:检查选择是否合法
if (isValid(state, choice)) {
// 尝试:做出选择,更新状态
makeChoice(state, choice);
// 进行下一轮选择
backtrack(state, [choice.left, choice.right], res);
// 回退:撤销选择,恢复到之前的状态
undoChoice(state);
}
}
}
``` ```
=== "C" === "C"

View file

@ -190,25 +190,180 @@ comments: true
=== "Go" === "Go"
```go title="n_queens.go" ```go title="n_queens.go"
[class]{}-[func]{backtrack} /* 回溯算法N 皇后 */
func backtrack(row, n int, state *[][]string, res *[][][]string, cols, diags1, diags2 *[]bool) {
// 当放置完所有行时,记录解
if row == n {
newState := make([][]string, len(*state))
for i, _ := range newState {
newState[i] = make([]string, len((*state)[0]))
copy(newState[i], (*state)[i])
[class]{}-[func]{nQueens} }
*res = append(*res, newState)
}
// 遍历所有列
for col := 0; col < n; col++ {
// 计算该格子对应的主对角线和副对角线
diag1 := row - col + n - 1
diag2 := row + col
// 剪枝:不允许该格子所在 (列 或 主对角线 或 副对角线) 包含皇后
if !((*cols)[col] || (*diags1)[diag1] || (*diags2)[diag2]) {
// 尝试:将皇后放置在该格子
(*state)[row][col] = "Q"
(*cols)[col], (*diags1)[diag1], (*diags2)[diag2] = true, true, true
// 放置下一行
backtrack(row+1, n, state, res, cols, diags1, diags2)
// 回退:将该格子恢复为空位
(*state)[row][col] = "#"
(*cols)[col], (*diags1)[diag1], (*diags2)[diag2] = false, false, false
}
}
}
/* 回溯算法N 皇后 */
func backtrack(row, n int, state *[][]string, res *[][][]string, cols, diags1, diags2 *[]bool) {
// 当放置完所有行时,记录解
if row == n {
newState := make([][]string, len(*state))
for i, _ := range newState {
newState[i] = make([]string, len((*state)[0]))
copy(newState[i], (*state)[i])
}
*res = append(*res, newState)
}
// 遍历所有列
for col := 0; col < n; col++ {
// 计算该格子对应的主对角线和副对角线
diag1 := row - col + n - 1
diag2 := row + col
// 剪枝:不允许该格子所在 (列 或 主对角线 或 副对角线) 包含皇后
if !((*cols)[col] || (*diags1)[diag1] || (*diags2)[diag2]) {
// 尝试:将皇后放置在该格子
(*state)[row][col] = "Q"
(*cols)[col], (*diags1)[diag1], (*diags2)[diag2] = true, true, true
// 放置下一行
backtrack(row+1, n, state, res, cols, diags1, diags2)
// 回退:将该格子恢复为空位
(*state)[row][col] = "#"
(*cols)[col], (*diags1)[diag1], (*diags2)[diag2] = false, false, false
}
}
}
func nQueens(n int) [][][]string {
// 初始化 n*n 大小的棋盘,其中 'Q' 代表皇后,'#' 代表空位
state := make([][]string, n)
for i := 0; i < n; i++ {
row := make([]string, n)
for i := 0; i < n; i++ {
row[i] = "#"
}
state[i] = row
}
// 记录列是否有皇后
cols := make([]bool, n)
diags1 := make([]bool, 2*n-1)
diags2 := make([]bool, 2*n-1)
res := make([][][]string, 0)
backtrack(0, n, &state, &res, &cols, &diags1, &diags2)
return res
}
``` ```
=== "JavaScript" === "JavaScript"
```javascript title="n_queens.js" ```javascript title="n_queens.js"
[class]{}-[func]{backtrack} /* 回溯算法N 皇后 */
function backtrack(row, n, state, res, cols, diags1, diags2) {
// 当放置完所有行时,记录解
if (row === n) {
res.push(state.map((row) => row.slice()));
return;
}
// 遍历所有列
for (let col = 0; col < n; col++) {
// 计算该格子对应的主对角线和副对角线
const diag1 = row - col + n - 1;
const diag2 = row + col;
// 剪枝:不允许该格子所在 (列 或 主对角线 或 副对角线) 包含皇后
if (!(cols[col] || diags1[diag1] || diags2[diag2])) {
// 尝试:将皇后放置在该格子
state[row][col] = 'Q';
cols[col] = diags1[diag1] = diags2[diag2] = true;
// 放置下一行
backtrack(row + 1, n, state, res, cols, diags1, diags2);
// 回退:将该格子恢复为空位
state[row][col] = '#';
cols[col] = diags1[diag1] = diags2[diag2] = false;
}
}
}
[class]{}-[func]{nQueens} /* 求解 N 皇后 */
function nQueens(n) {
// 初始化 n*n 大小的棋盘,其中 'Q' 代表皇后,'#' 代表空位
const state = Array.from({ length: n }, () => Array(n).fill('#'));
const cols = Array(n).fill(false); // 记录列是否有皇后
const diags1 = Array(2 * n - 1).fill(false); // 记录主对角线是否有皇后
const diags2 = Array(2 * n - 1).fill(false); // 记录副对角线是否有皇后
const res = [];
backtrack(0, n, state, res, cols, diags1, diags2);
return res;
}
``` ```
=== "TypeScript" === "TypeScript"
```typescript title="n_queens.ts" ```typescript title="n_queens.ts"
[class]{}-[func]{backtrack} /* 回溯算法N 皇后 */
function backtrack(
row: number,
n: number,
state: string[][],
res: string[][][],
cols: boolean[],
diags1: boolean[],
diags2: boolean[]
): void {
// 当放置完所有行时,记录解
if (row === n) {
res.push(state.map((row) => row.slice()));
return;
}
// 遍历所有列
for (let col = 0; col < n; col++) {
// 计算该格子对应的主对角线和副对角线
const diag1 = row - col + n - 1;
const diag2 = row + col;
// 剪枝:不允许该格子所在 (列 或 主对角线 或 副对角线) 包含皇后
if (!(cols[col] || diags1[diag1] || diags2[diag2])) {
// 尝试:将皇后放置在该格子
state[row][col] = 'Q';
cols[col] = diags1[diag1] = diags2[diag2] = true;
// 放置下一行
backtrack(row + 1, n, state, res, cols, diags1, diags2);
// 回退:将该格子恢复为空位
state[row][col] = '#';
cols[col] = diags1[diag1] = diags2[diag2] = false;
}
}
}
[class]{}-[func]{nQueens} /* 求解 N 皇后 */
function nQueens(n: number): string[][][] {
// 初始化 n*n 大小的棋盘,其中 'Q' 代表皇后,'#' 代表空位
const state = Array.from({ length: n }, () => Array(n).fill('#'));
const cols = Array(n).fill(false); // 记录列是否有皇后
const diags1 = Array(2 * n - 1).fill(false); // 记录主对角线是否有皇后
const diags2 = Array(2 * n - 1).fill(false); // 记录副对角线是否有皇后
const res: string[][][] = [];
backtrack(0, n, state, res, cols, diags1, diags2);
return res;
}
``` ```
=== "C" === "C"
@ -278,9 +433,49 @@ comments: true
=== "Swift" === "Swift"
```swift title="n_queens.swift" ```swift title="n_queens.swift"
[class]{}-[func]{backtrack} /* 回溯算法N 皇后 */
func backtrack(row: Int, n: Int, state: inout [[String]], res: inout [[[String]]], cols: inout [Bool], diags1: inout [Bool], diags2: inout [Bool]) {
// 当放置完所有行时,记录解
if row == n {
res.append(state)
return
}
// 遍历所有列
for col in 0 ..< n {
// 计算该格子对应的主对角线和副对角线
let diag1 = row - col + n - 1
let diag2 = row + col
// 剪枝:不允许该格子所在 (列 或 主对角线 或 副对角线) 包含皇后
if !(cols[col] || diags1[diag1] || diags2[diag2]) {
// 尝试:将皇后放置在该格子
state[row][col] = "Q"
cols[col] = true
diags1[diag1] = true
diags2[diag2] = true
// 放置下一行
backtrack(row: row + 1, n: n, state: &state, res: &res, cols: &cols, diags1: &diags1, diags2: &diags2)
// 回退:将该格子恢复为空位
state[row][col] = "#"
cols[col] = false
diags1[diag1] = false
diags2[diag2] = false
}
}
}
[class]{}-[func]{nQueens} /* 求解 N 皇后 */
func nQueens(n: Int) -> [[[String]]] {
// 初始化 n*n 大小的棋盘,其中 'Q' 代表皇后,'#' 代表空位
var state = Array(repeating: Array(repeating: "#", count: n), count: n)
var cols = Array(repeating: false, count: n) // 记录列是否有皇后
var diags1 = Array(repeating: false, count: 2 * n - 1) // 记录主对角线是否有皇后
var diags2 = Array(repeating: false, count: 2 * n - 1) // 记录副对角线是否有皇后
var res: [[[String]]] = []
backtrack(row: 0, n: n, state: &state, res: &res, cols: &cols, diags1: &diags1, diags2: &diags2)
return res
}
``` ```
=== "Zig" === "Zig"

View file

@ -140,25 +140,111 @@ comments: true
=== "Go" === "Go"
```go title="permutations_i.go" ```go title="permutations_i.go"
[class]{}-[func]{backtrack} /* 回溯算法:全排列 I */
func backtrackI(state *[]int, choices *[]int, selected *[]bool, res *[][]int) {
// 当状态长度等于元素数量时,记录解
if len(*state) == len(*choices) {
newState := append([]int{}, *state...)
*res = append(*res, newState)
}
// 遍历所有选择
for i := 0; i < len(*choices); i++ {
choice := (*choices)[i]
// 剪枝:不允许重复选择元素 且 不允许重复选择相等元素
if !(*selected)[i] {
// 尝试:做出选择,更新状态
(*selected)[i] = true
*state = append(*state, choice)
// 进行下一轮选择
backtrackI(state, choices, selected, res)
// 回退:撤销选择,恢复到之前的状态
(*selected)[i] = false
*state = (*state)[:len(*state)-1]
}
}
}
[class]{}-[func]{permutationsI} /* 全排列 I */
func permutationsI(nums []int) [][]int {
res := make([][]int, 0)
state := make([]int, 0)
selected := make([]bool, len(nums))
backtrackI(&state, &nums, &selected, &res)
return res
}
``` ```
=== "JavaScript" === "JavaScript"
```javascript title="permutations_i.js" ```javascript title="permutations_i.js"
[class]{}-[func]{backtrack} /* 回溯算法:全排列 I */
function backtrack(state, choices, selected, res) {
// 当状态长度等于元素数量时,记录解
if (state.length === choices.length) {
res.push([...state]);
return;
}
// 遍历所有选择
choices.forEach((choice, i) => {
// 剪枝:不允许重复选择元素 且 不允许重复选择相等元素
if (!selected[i]) {
// 尝试:做出选择,更新状态
selected[i] = true;
state.push(choice);
// 进行下一轮选择
backtrack(state, choices, selected, res);
// 回退:撤销选择,恢复到之前的状态
selected[i] = false;
state.pop();
}
});
}
[class]{}-[func]{permutationsI} /* 全排列 I */
function permutationsI(nums) {
const res = [];
backtrack([], nums, Array(nums.length).fill(false), res);
return res;
}
``` ```
=== "TypeScript" === "TypeScript"
```typescript title="permutations_i.ts" ```typescript title="permutations_i.ts"
[class]{}-[func]{backtrack} /* 回溯算法:全排列 I */
function backtrack(
state: number[],
choices: number[],
selected: boolean[],
res: number[][]
): void {
// 当状态长度等于元素数量时,记录解
if (state.length === choices.length) {
res.push([...state]);
return;
}
// 遍历所有选择
choices.forEach((choice, i) => {
// 剪枝:不允许重复选择元素 且 不允许重复选择相等元素
if (!selected[i]) {
// 尝试:做出选择,更新状态
selected[i] = true;
state.push(choice);
// 进行下一轮选择
backtrack(state, choices, selected, res);
// 回退:撤销选择,恢复到之前的状态
selected[i] = false;
state.pop();
}
});
}
[class]{}-[func]{permutationsI} /* 全排列 I */
function permutationsI(nums: number[]): number[][] {
const res: number[][] = [];
backtrack([], nums, Array(nums.length).fill(false), res);
return res;
}
``` ```
=== "C" === "C"
@ -388,25 +474,118 @@ comments: true
=== "Go" === "Go"
```go title="permutations_ii.go" ```go title="permutations_ii.go"
[class]{}-[func]{backtrack} /* 回溯算法:全排列 II */
func backtrackII(state *[]int, choices *[]int, selected *[]bool, res *[][]int) {
// 当状态长度等于元素数量时,记录解
if len(*state) == len(*choices) {
newState := append([]int{}, *state...)
*res = append(*res, newState)
}
// 遍历所有选择
duplicated := make(map[int]struct{}, 0)
for i := 0; i < len(*choices); i++ {
choice := (*choices)[i]
// 剪枝:不允许重复选择元素 且 不允许重复选择相等元素
if _, ok := duplicated[choice]; !ok && !(*selected)[i] {
// 尝试:做出选择,更新状态
// 记录选择过的元素值
duplicated[choice] = struct{}{}
(*selected)[i] = true
*state = append(*state, choice)
// 进行下一轮选择
backtrackI(state, choices, selected, res)
// 回退:撤销选择,恢复到之前的状态
(*selected)[i] = false
*state = (*state)[:len(*state)-1]
}
}
}
[class]{}-[func]{permutationsII} /* 全排列 II */
func permutationsII(nums []int) [][]int {
res := make([][]int, 0)
state := make([]int, 0)
selected := make([]bool, len(nums))
backtrackII(&state, &nums, &selected, &res)
return res
}
``` ```
=== "JavaScript" === "JavaScript"
```javascript title="permutations_ii.js" ```javascript title="permutations_ii.js"
[class]{}-[func]{backtrack} /* 回溯算法:全排列 II */
function backtrack(state, choices, selected, res) {
// 当状态长度等于元素数量时,记录解
if (state.length === choices.length) {
res.push([...state]);
return;
}
// 遍历所有选择
const duplicated = new Set();
choices.forEach((choice, i) => {
// 剪枝:不允许重复选择元素 且 不允许重复选择相等元素
if (!selected[i] && !duplicated.has(choice)) {
// 尝试:做出选择,更新状态
duplicated.add(choice); // 记录选择过的元素值
selected[i] = true;
state.push(choice);
// 进行下一轮选择
backtrack(state, choices, selected, res);
// 回退:撤销选择,恢复到之前的状态
selected[i] = false;
state.pop();
}
});
}
[class]{}-[func]{permutationsII} /* 全排列 II */
function permutationsII(nums) {
const res = [];
backtrack([], nums, Array(nums.length).fill(false), res);
return res;
}
``` ```
=== "TypeScript" === "TypeScript"
```typescript title="permutations_ii.ts" ```typescript title="permutations_ii.ts"
[class]{}-[func]{backtrack} /* 回溯算法:全排列 II */
function backtrack(
state: number[],
choices: number[],
selected: boolean[],
res: number[][]
): void {
// 当状态长度等于元素数量时,记录解
if (state.length === choices.length) {
res.push([...state]);
return;
}
// 遍历所有选择
const duplicated = new Set();
choices.forEach((choice, i) => {
// 剪枝:不允许重复选择元素 且 不允许重复选择相等元素
if (!selected[i] && !duplicated.has(choice)) {
// 尝试:做出选择,更新状态
duplicated.add(choice); // 记录选择过的元素值
selected[i] = true;
state.push(choice);
// 进行下一轮选择
backtrack(state, choices, selected, res);
// 回退:撤销选择,恢复到之前的状态
selected[i] = false;
state.pop();
}
});
}
[class]{}-[func]{permutationsII} /* 全排列 II */
function permutationsII(nums: number[]): number[][] {
const res: number[][] = [];
backtrack([], nums, Array(nums.length).fill(false), res);
return res;
}
``` ```
=== "C" === "C"

View file

@ -34,7 +34,7 @@ comments: true
// 1. 将数组元素分配到各个桶中 // 1. 将数组元素分配到各个桶中
for (float num : nums) { for (float num : nums) {
// 输入数据范围 [0, 1),使用 num * k 映射到索引范围 [0, k-1] // 输入数据范围 [0, 1),使用 num * k 映射到索引范围 [0, k-1]
int i = (int) num * k; int i = (int) (num * k);
// 将 num 添加进桶 i // 将 num 添加进桶 i
buckets.get(i).add(num); buckets.get(i).add(num);
} }
@ -123,7 +123,7 @@ comments: true
// 1. 将数组元素分配到各个桶中 // 1. 将数组元素分配到各个桶中
for _, num := range nums { for _, num := range nums {
// 输入数据范围 [0, 1),使用 num * k 映射到索引范围 [0, k-1] // 输入数据范围 [0, 1),使用 num * k 映射到索引范围 [0, k-1]
i := int(num) * k i := int(num * float64(k))
// 将 num 添加进桶 i // 将 num 添加进桶 i
buckets[i] = append(buckets[i], num) buckets[i] = append(buckets[i], num)
} }
@ -229,7 +229,7 @@ comments: true
// 1. 将数组元素分配到各个桶中 // 1. 将数组元素分配到各个桶中
foreach (float num in nums) { foreach (float num in nums) {
// 输入数据范围 [0, 1),使用 num * k 映射到索引范围 [0, k-1] // 输入数据范围 [0, 1),使用 num * k 映射到索引范围 [0, k-1]
int i = (int)num * k; int i = (int) (num * k);
// 将 num 添加进桶 i // 将 num 添加进桶 i
buckets[i].Add(num); buckets[i].Add(num);
} }
@ -259,7 +259,7 @@ comments: true
// 1. 将数组元素分配到各个桶中 // 1. 将数组元素分配到各个桶中
for num in nums { for num in nums {
// 输入数据范围 [0, 1),使用 num * k 映射到索引范围 [0, k-1] // 输入数据范围 [0, 1),使用 num * k 映射到索引范围 [0, k-1]
let i = Int(num) * k let i = Int(num * k)
// 将 num 添加进桶 i // 将 num 添加进桶 i
buckets[i].append(num) buckets[i].append(num)
} }

View file

@ -103,7 +103,7 @@ comments: true
func countingSortNaive(nums []int) { func countingSortNaive(nums []int) {
// 1. 统计数组最大元素 m // 1. 统计数组最大元素 m
m := 0 m := 0
for num := range nums { for _, num := range nums {
if num > m { if num > m {
m = num m = num
} }
@ -424,7 +424,7 @@ $$
func countingSort(nums []int) { func countingSort(nums []int) {
// 1. 统计数组最大元素 m // 1. 统计数组最大元素 m
m := 0 m := 0
for num := range nums { for _, num := range nums {
if num > m { if num > m {
m = num m = num
} }