From e519d9b6c2dc38da0d225481399ba70f27a66c6d Mon Sep 17 00:00:00 2001 From: krahets Date: Thu, 4 May 2023 05:32:09 +0800 Subject: [PATCH] build --- chapter_backtracking/n_queens_problem.md | 6 +- chapter_backtracking/permutations_problem.md | 66 ++++++++++++++++++-- 2 files changed, 65 insertions(+), 7 deletions(-) diff --git a/chapter_backtracking/n_queens_problem.md b/chapter_backtracking/n_queens_problem.md index 58b5771d8..b0753efa5 100644 --- a/chapter_backtracking/n_queens_problem.md +++ b/chapter_backtracking/n_queens_problem.md @@ -148,10 +148,10 @@ comments: true row: int, n: int, state: list[list[str]], + res: list[list[list[str]]], cols: list[bool], diags1: list[bool], diags2: list[bool], - res: list[list[list[str]]], ): """回溯算法:N 皇后""" # 当放置完所有行时,记录解 @@ -169,7 +169,7 @@ comments: true state[row][col] = "Q" cols[col] = diags1[diag1] = diags2[diag2] = True # 放置下一行 - backtrack(row + 1, n, state, cols, diags1, diags2, res) + backtrack(row + 1, n, state, res, cols, diags1, diags2) # 回退:将该格子恢复为空位 state[row][col] = "#" cols[col] = diags1[diag1] = diags2[diag2] = False @@ -182,7 +182,7 @@ comments: true diags1 = [False] * (2 * n - 1) # 记录主对角线是否有皇后 diags2 = [False] * (2 * n - 1) # 记录副对角线是否有皇后 res = [] - backtrack(0, n, state, cols, diags1, diags2, res) + backtrack(0, n, state, res, cols, diags1, diags2) return res ``` diff --git a/chapter_backtracking/permutations_problem.md b/chapter_backtracking/permutations_problem.md index f19b320f0..90218dd13 100644 --- a/chapter_backtracking/permutations_problem.md +++ b/chapter_backtracking/permutations_problem.md @@ -207,9 +207,37 @@ comments: true === "Swift" ```swift title="permutations_i.swift" - [class]{}-[func]{backtrack} + /* 回溯算法:全排列 I */ + func backtrack(state: inout [Int], choices: [Int], selected: inout [Bool], res: inout [[Int]]) { + // 当状态长度等于元素数量时,记录解 + if state.count == choices.count { + res.append(state) + return + } + // 遍历所有选择 + for (i, choice) in choices.enumerated() { + // 剪枝:不允许重复选择元素 且 不允许重复选择相等元素 + if !selected[i] { + // 尝试:做出选择,更新状态 + selected[i] = true + state.append(choice) + // 进行下一轮选择 + backtrack(state: &state, choices: choices, selected: &selected, res: &res) + // 回退:撤销选择,恢复到之前的状态 + selected[i] = false + state.removeLast() + } + } + } - [class]{}-[func]{permutationsI} + /* 全排列 I */ + func permutationsI(nums: [Int]) -> [[Int]] { + var state: [Int] = [] + var selected = Array(repeating: false, count: nums.count) + var res: [[Int]] = [] + backtrack(state: &state, choices: nums, selected: &selected, res: &res) + return res + } ``` === "Zig" @@ -429,9 +457,39 @@ comments: true === "Swift" ```swift title="permutations_ii.swift" - [class]{}-[func]{backtrack} + /* 回溯算法:全排列 II */ + func backtrack(state: inout [Int], choices: [Int], selected: inout [Bool], res: inout [[Int]]) { + // 当状态长度等于元素数量时,记录解 + if state.count == choices.count { + res.append(state) + return + } + // 遍历所有选择 + var duplicated: Set = [] + for (i, choice) in choices.enumerated() { + // 剪枝:不允许重复选择元素 且 不允许重复选择相等元素 + if !selected[i], !duplicated.contains(choice) { + // 尝试:做出选择,更新状态 + duplicated.insert(choice) // 记录选择过的元素值 + selected[i] = true + state.append(choice) + // 进行下一轮选择 + backtrack(state: &state, choices: choices, selected: &selected, res: &res) + // 回退:撤销选择,恢复到之前的状态 + selected[i] = false + state.removeLast() + } + } + } - [class]{}-[func]{permutationsII} + /* 全排列 II */ + func permutationsII(nums: [Int]) -> [[Int]] { + var state: [Int] = [] + var selected = Array(repeating: false, count: nums.count) + var res: [[Int]] = [] + backtrack(state: &state, choices: nums, selected: &selected, res: &res) + return res + } ``` === "Zig"