diff --git a/codes/swift/Package.swift b/codes/swift/Package.swift index 73e1e82e9..8d2716049 100644 --- a/codes/swift/Package.swift +++ b/codes/swift/Package.swift @@ -61,6 +61,7 @@ let package = Package( .executable(name: "preorder_traversal_iii_template", targets: ["preorder_traversal_iii_template"]), .executable(name: "permutations_i", targets: ["permutations_i"]), .executable(name: "permutations_ii", targets: ["permutations_ii"]), + .executable(name: "n_queens", targets: ["n_queens"]), ], targets: [ // helper @@ -122,5 +123,6 @@ let package = Package( .executableTarget(name: "preorder_traversal_iii_template", dependencies: ["utils"], path: "chapter_backtracking", sources: ["preorder_traversal_iii_template.swift"]), .executableTarget(name: "permutations_i", path: "chapter_backtracking", sources: ["permutations_i.swift"]), .executableTarget(name: "permutations_ii", path: "chapter_backtracking", sources: ["permutations_ii.swift"]), + .executableTarget(name: "n_queens", path: "chapter_backtracking", sources: ["n_queens.swift"]), ] ) diff --git a/codes/swift/chapter_backtracking/n_queens.swift b/codes/swift/chapter_backtracking/n_queens.swift new file mode 100644 index 000000000..e9d07d839 --- /dev/null +++ b/codes/swift/chapter_backtracking/n_queens.swift @@ -0,0 +1,67 @@ +/** + * File: n_queens.swift + * Created Time: 2023-05-14 + * Author: nuomi1 (nuomi1@qq.com) + */ + +/* 回溯算法: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 + } + } +} + +/* 求解 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 +} + +@main +enum NQueens { + /* Driver Code */ + static func main() { + let n = 4 + let res = nQueens(n: n) + + print("输入棋盘长宽为 \(n)") + print("皇后放置方案共有 \(res.count) 种") + for state in res { + print("--------------------") + for row in state { + print(row) + } + } + } +} diff --git a/codes/swift/chapter_backtracking/preorder_traversal_iii_template.swift b/codes/swift/chapter_backtracking/preorder_traversal_iii_template.swift index 9f83e9f56..bd8ad879d 100644 --- a/codes/swift/chapter_backtracking/preorder_traversal_iii_template.swift +++ b/codes/swift/chapter_backtracking/preorder_traversal_iii_template.swift @@ -53,7 +53,7 @@ func backtrack(state: inout [TreeNode], choices: [TreeNode], res: inout [[TreeNo } @main -enum preorder_traversal_iii_template { +enum PreorderTraversalIIITemplate { /* Driver Code */ static func main() { let root = TreeNode.listToTree(list: [1, 7, 3, 4, 5, 6, 7])