From 561ef204624260e9e7c182e0f2974b3c1a5f3f8a Mon Sep 17 00:00:00 2001 From: nuomi1 Date: Wed, 3 May 2023 18:45:43 +0800 Subject: [PATCH] feat: add Swift codes for backtracking_algorithm article (#480) * fix: compile error * fix: package define * feat: add Swift codes for backtracking_algorithm article --- codes/swift/Package.swift | 20 ++++- .../preorder_traversal_i_compact.swift | 43 +++++++++++ .../preorder_traversal_ii_compact.swift | 51 ++++++++++++ .../preorder_traversal_iii_compact.swift | 52 +++++++++++++ .../preorder_traversal_iii_template.swift | 77 +++++++++++++++++++ codes/swift/chapter_tree/avl_tree.swift | 2 +- .../chapter_tree/binary_search_tree.swift | 2 +- 7 files changed, 241 insertions(+), 6 deletions(-) create mode 100644 codes/swift/chapter_backtracking/preorder_traversal_i_compact.swift create mode 100644 codes/swift/chapter_backtracking/preorder_traversal_ii_compact.swift create mode 100644 codes/swift/chapter_backtracking/preorder_traversal_iii_compact.swift create mode 100644 codes/swift/chapter_backtracking/preorder_traversal_iii_template.swift diff --git a/codes/swift/Package.swift b/codes/swift/Package.swift index 7e7993cac..7bcffd5df 100644 --- a/codes/swift/Package.swift +++ b/codes/swift/Package.swift @@ -9,7 +9,6 @@ let package = Package( .executable(name: "time_complexity", targets: ["time_complexity"]), .executable(name: "worst_best_time_complexity", targets: ["worst_best_time_complexity"]), .executable(name: "space_complexity", targets: ["space_complexity"]), - .executable(name: "leetcode_two_sum", targets: ["leetcode_two_sum"]), // chapter_array_and_linkedlist .executable(name: "array", targets: ["array"]), .executable(name: "linked_list", targets: ["linked_list"]), @@ -25,6 +24,8 @@ let package = Package( .executable(name: "deque", targets: ["deque"]), .executable(name: "linkedlist_deque", targets: ["linkedlist_deque"]), .executable(name: "array_deque", targets: ["array_deque"]), + // chapter_binary_search + .executable(name: "binary_search", targets: ["binary_search"]), // chapter_hashing .executable(name: "hash_map", targets: ["hash_map"]), .executable(name: "array_hash_map", targets: ["array_hash_map"]), @@ -42,8 +43,8 @@ let package = Package( .executable(name: "graph_bfs", targets: ["graph_bfs"]), .executable(name: "graph_dfs", targets: ["graph_dfs"]), // chapter_searching + .executable(name: "leetcode_two_sum", targets: ["leetcode_two_sum"]), .executable(name: "linear_search", targets: ["linear_search"]), - .executable(name: "binary_search", targets: ["binary_search"]), .executable(name: "hashing_search", targets: ["hashing_search"]), // chapter_sorting .executable(name: "bubble_sort", targets: ["bubble_sort"]), @@ -53,6 +54,11 @@ let package = Package( .executable(name: "bucket_sort", targets: ["bucket_sort"]), .executable(name: "counting_sort", targets: ["counting_sort"]), .executable(name: "radix_sort", targets: ["radix_sort"]), + // chapter_backtracking + .executable(name: "preorder_traversal_i_compact", targets: ["preorder_traversal_i_compact"]), + .executable(name: "preorder_traversal_ii_compact", targets: ["preorder_traversal_ii_compact"]), + .executable(name: "preorder_traversal_iii_compact", targets: ["preorder_traversal_iii_compact"]), + .executable(name: "preorder_traversal_iii_template", targets: ["preorder_traversal_iii_template"]), ], targets: [ // helper @@ -62,7 +68,6 @@ let package = Package( .executableTarget(name: "time_complexity", path: "chapter_computational_complexity", sources: ["time_complexity.swift"]), .executableTarget(name: "worst_best_time_complexity", path: "chapter_computational_complexity", sources: ["worst_best_time_complexity.swift"]), .executableTarget(name: "space_complexity", dependencies: ["utils"], path: "chapter_computational_complexity", sources: ["space_complexity.swift"]), - .executableTarget(name: "leetcode_two_sum", path: "chapter_computational_complexity", sources: ["leetcode_two_sum.swift"]), // chapter_array_and_linkedlist .executableTarget(name: "array", path: "chapter_array_and_linkedlist", sources: ["array.swift"]), .executableTarget(name: "linked_list", dependencies: ["utils"], path: "chapter_array_and_linkedlist", sources: ["linked_list.swift"]), @@ -78,6 +83,8 @@ let package = Package( .executableTarget(name: "deque", path: "chapter_stack_and_queue", sources: ["deque.swift"]), .executableTarget(name: "linkedlist_deque", path: "chapter_stack_and_queue", sources: ["linkedlist_deque.swift"]), .executableTarget(name: "array_deque", path: "chapter_stack_and_queue", sources: ["array_deque.swift"]), + // chapter_binary_search + .executableTarget(name: "binary_search", path: "chapter_binary_search", sources: ["binary_search.swift"]), // chapter_hashing .executableTarget(name: "hash_map", dependencies: ["utils"], path: "chapter_hashing", sources: ["hash_map.swift"]), .executableTarget(name: "array_hash_map", path: "chapter_hashing", sources: ["array_hash_map.swift"]), @@ -95,8 +102,8 @@ let package = Package( .executableTarget(name: "graph_bfs", dependencies: ["utils", "graph_adjacency_list_target"], path: "chapter_graph", sources: ["graph_bfs.swift"]), .executableTarget(name: "graph_dfs", dependencies: ["utils", "graph_adjacency_list_target"], path: "chapter_graph", sources: ["graph_dfs.swift"]), // chapter_searching + .executableTarget(name: "leetcode_two_sum", path: "chapter_searching", sources: ["leetcode_two_sum.swift"]), .executableTarget(name: "linear_search", dependencies: ["utils"], path: "chapter_searching", sources: ["linear_search.swift"]), - .executableTarget(name: "binary_search", path: "chapter_searching", sources: ["binary_search.swift"]), .executableTarget(name: "hashing_search", dependencies: ["utils"], path: "chapter_searching", sources: ["hashing_search.swift"]), // chapter_sorting .executableTarget(name: "bubble_sort", path: "chapter_sorting", sources: ["bubble_sort.swift"]), @@ -106,5 +113,10 @@ let package = Package( .executableTarget(name: "bucket_sort", path: "chapter_sorting", sources: ["bucket_sort.swift"]), .executableTarget(name: "counting_sort", path: "chapter_sorting", sources: ["counting_sort.swift"]), .executableTarget(name: "radix_sort", path: "chapter_sorting", sources: ["radix_sort.swift"]), + // chapter_backtracking + .executableTarget(name: "preorder_traversal_i_compact", dependencies: ["utils"], path: "chapter_backtracking", sources: ["preorder_traversal_i_compact.swift"]), + .executableTarget(name: "preorder_traversal_ii_compact", dependencies: ["utils"], path: "chapter_backtracking", sources: ["preorder_traversal_ii_compact.swift"]), + .executableTarget(name: "preorder_traversal_iii_compact", dependencies: ["utils"], path: "chapter_backtracking", sources: ["preorder_traversal_iii_compact.swift"]), + .executableTarget(name: "preorder_traversal_iii_template", dependencies: ["utils"], path: "chapter_backtracking", sources: ["preorder_traversal_iii_template.swift"]), ] ) diff --git a/codes/swift/chapter_backtracking/preorder_traversal_i_compact.swift b/codes/swift/chapter_backtracking/preorder_traversal_i_compact.swift new file mode 100644 index 000000000..1e656e70e --- /dev/null +++ b/codes/swift/chapter_backtracking/preorder_traversal_i_compact.swift @@ -0,0 +1,43 @@ +/** + * File: preorder_traversal_i_compact.swift + * Created Time: 2023-04-30 + * Author: nuomi1 (nuomi1@qq.com) + */ + +import utils + +var res: [TreeNode] = [] + +/* 前序遍历:例题一 */ +func preOrder(root: TreeNode?) { + guard let root = root else { + return + } + if root.val == 7 { + // 记录解 + res.append(root) + } + preOrder(root: root.left) + preOrder(root: root.right) +} + +@main +enum PreorderTraversalICompact { + /* Driver Code */ + static func main() { + let root = TreeNode.listToTree(list: [1, 7, 3, 4, 5, 6, 7]) + print("\n初始化二叉树") + PrintUtil.printTree(root: root) + + // 前序遍历 + res = [] + preOrder(root: root) + + print("\n输出所有值为 7 的节点") + var vals: [Int] = [] + for node in res { + vals.append(node.val) + } + print(vals) + } +} diff --git a/codes/swift/chapter_backtracking/preorder_traversal_ii_compact.swift b/codes/swift/chapter_backtracking/preorder_traversal_ii_compact.swift new file mode 100644 index 000000000..24205db2f --- /dev/null +++ b/codes/swift/chapter_backtracking/preorder_traversal_ii_compact.swift @@ -0,0 +1,51 @@ +/** + * File: preorder_traversal_ii_compact.swift + * Created Time: 2023-04-30 + * Author: nuomi1 (nuomi1@qq.com) + */ + +import utils + +var path: [TreeNode] = [] +var res: [[TreeNode]] = [] + +/* 前序遍历:例题二 */ +func preOrder(root: TreeNode?) { + guard let root = root else { + return + } + // 尝试 + path.append(root) + if root.val == 7 { + // 记录解 + res.append(path) + } + preOrder(root: root.left) + preOrder(root: root.right) + // 回退 + path.removeLast() +} + +@main +enum PreorderTraversalIICompact { + /* Driver Code */ + static func main() { + let root = TreeNode.listToTree(list: [1, 7, 3, 4, 5, 6, 7]) + print("\n初始化二叉树") + PrintUtil.printTree(root: root) + + // 前序遍历 + path = [] + res = [] + preOrder(root: root) + + print("\n输出所有根节点到节点 7 的路径") + for path in res { + var vals: [Int] = [] + for node in path { + vals.append(node.val) + } + print(vals) + } + } +} diff --git a/codes/swift/chapter_backtracking/preorder_traversal_iii_compact.swift b/codes/swift/chapter_backtracking/preorder_traversal_iii_compact.swift new file mode 100644 index 000000000..581b89d2f --- /dev/null +++ b/codes/swift/chapter_backtracking/preorder_traversal_iii_compact.swift @@ -0,0 +1,52 @@ +/** + * File: preorder_traversal_iii_compact.swift + * Created Time: 2023-04-30 + * Author: nuomi1 (nuomi1@qq.com) + */ + +import utils + +var path: [TreeNode] = [] +var res: [[TreeNode]] = [] + +/* 前序遍历:例题三 */ +func preOrder(root: TreeNode?) { + // 剪枝 + guard let root = root, root.val != 3 else { + return + } + // 尝试 + path.append(root) + if root.val == 7 { + // 记录解 + res.append(path) + } + preOrder(root: root.left) + preOrder(root: root.right) + // 回退 + path.removeLast() +} + +@main +enum PreorderTraversalIIICompact { + /* Driver Code */ + static func main() { + let root = TreeNode.listToTree(list: [1, 7, 3, 4, 5, 6, 7]) + print("\n初始化二叉树") + PrintUtil.printTree(root: root) + + // 前序遍历 + path = [] + res = [] + preOrder(root: root) + + print("\n输出所有根节点到节点 7 的路径,且路径中不包含值为 3 的节点") + for path in res { + var vals: [Int] = [] + for node in path { + vals.append(node.val) + } + print(vals) + } + } +} diff --git a/codes/swift/chapter_backtracking/preorder_traversal_iii_template.swift b/codes/swift/chapter_backtracking/preorder_traversal_iii_template.swift new file mode 100644 index 000000000..9f83e9f56 --- /dev/null +++ b/codes/swift/chapter_backtracking/preorder_traversal_iii_template.swift @@ -0,0 +1,77 @@ +/** + * File: preorder_traversal_iii_template.swift + * Created Time: 2023-04-30 + * Author: nuomi1 (nuomi1@qq.com) + */ + +import utils + +/* 判断当前状态是否为解 */ +func isSolution(state: [TreeNode]) -> Bool { + !state.isEmpty && state.last!.val == 7 +} + +/* 记录解 */ +func recordSolution(state: [TreeNode], res: inout [[TreeNode]]) { + res.append(state) +} + +/* 判断在当前状态下,该选择是否合法 */ +func isValid(state: [TreeNode], choice: TreeNode?) -> Bool { + choice != nil && choice!.val != 3 +} + +/* 更新状态 */ +func makeChoice(state: inout [TreeNode], choice: TreeNode) { + state.append(choice) +} + +/* 恢复状态 */ +func undoChoice(state: inout [TreeNode], choice: TreeNode) { + state.removeLast() +} + +/* 回溯算法:例题三 */ +func backtrack(state: inout [TreeNode], choices: [TreeNode], res: inout [[TreeNode]]) { + // 检查是否为解 + if isSolution(state: state) { + recordSolution(state: state, res: &res) + return + } + // 遍历所有选择 + for choice in choices { + // 剪枝:检查选择是否合法 + if isValid(state: state, choice: choice) { + // 尝试:做出选择,更新状态 + makeChoice(state: &state, choice: choice) + // 进行下一轮选择 + backtrack(state: &state, choices: [choice.left, choice.right].compactMap { $0 }, res: &res) + // 回退:撤销选择,恢复到之前的状态 + undoChoice(state: &state, choice: choice) + } + } +} + +@main +enum preorder_traversal_iii_template { + /* Driver Code */ + static func main() { + let root = TreeNode.listToTree(list: [1, 7, 3, 4, 5, 6, 7]) + print("\n初始化二叉树") + PrintUtil.printTree(root: root) + + // 回溯算法 + var state: [TreeNode] = [] + var res: [[TreeNode]] = [] + backtrack(state: &state, choices: [root].compactMap { $0 }, res: &res) + + print("\n输出所有根节点到节点 7 的路径,且路径中不包含值为 3 的节点") + for path in res { + var vals: [Int] = [] + for node in path { + vals.append(node.val) + } + print(vals) + } + } +} diff --git a/codes/swift/chapter_tree/avl_tree.swift b/codes/swift/chapter_tree/avl_tree.swift index 087b5975b..9d7df60e3 100644 --- a/codes/swift/chapter_tree/avl_tree.swift +++ b/codes/swift/chapter_tree/avl_tree.swift @@ -145,7 +145,7 @@ class AVLTree { } } else { // 子节点数量 = 2 ,则将中序遍历的下个节点删除,并用该节点替换当前节点 - let temp = node?.right + var temp = node?.right while temp?.left != nil { temp = temp?.left } diff --git a/codes/swift/chapter_tree/binary_search_tree.swift b/codes/swift/chapter_tree/binary_search_tree.swift index 3ea129a19..d1596661a 100644 --- a/codes/swift/chapter_tree/binary_search_tree.swift +++ b/codes/swift/chapter_tree/binary_search_tree.swift @@ -132,7 +132,7 @@ class BinarySearchTree { // 子节点数量 = 2 else { // 获取中序遍历中 cur 的下一个节点 - let tmp = cur?.right + var tmp = cur?.right while tmp?.left != nil { tmp = tmp?.left }