Skip to content

Commit

Permalink
Review Swift codes (#1150)
Browse files Browse the repository at this point in the history
* feat(swift): review for chapter_computational_complexity

* feat(swift): review for chapter_data_structure

* feat(swift): review for chapter_array_and_linkedlist

* feat(swift): review for chapter_stack_and_queue

* feat(swift): review for chapter_hashing

* feat(swift): review for chapter_tree

* feat(swift): add codes for heap article

* feat(swift): review for chapter_heap

* feat(swift): review for chapter_graph

* feat(swift): review for chapter_searching

* feat(swift): review for chapter_sorting

* feat(swift): review for chapter_divide_and_conquer

* feat(swift): review for chapter_backtracking

* feat(swift): review for chapter_dynamic_programming

* feat(swift): review for chapter_greedy

* feat(swift): review for utils

* feat(swift): update ci tool

* feat(swift): trailing closure

* feat(swift): array init

* feat(swift): map index
  • Loading branch information
nuomi1 authored Mar 20, 2024
1 parent 300a781 commit 7359a7c
Show file tree
Hide file tree
Showing 55 changed files with 293 additions and 224 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/swift.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
swift: ["5.9", "5.8.1", "5.7.3"]
swift: ["5.10", "5.9", "5.8"]
steps:
- uses: swift-actions/setup-swift@v1
- uses: swift-actions/setup-swift@v2
with:
swift-version: ${{ matrix.swift }}
- uses: actions/checkout@v4
Expand Down
2 changes: 2 additions & 0 deletions codes/swift/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ let package = Package(
.executable(name: "binary_search_tree", targets: ["binary_search_tree"]),
.executable(name: "avl_tree", targets: ["avl_tree"]),
// chapter_heap
.executable(name: "heap", targets: ["heap"]),
.executable(name: "my_heap", targets: ["my_heap"]),
.executable(name: "top_k", targets: ["top_k"]),
// chapter_graph
Expand Down Expand Up @@ -143,6 +144,7 @@ let package = Package(
.executableTarget(name: "binary_search_tree", dependencies: ["utils"], path: "chapter_tree", sources: ["binary_search_tree.swift"]),
.executableTarget(name: "avl_tree", dependencies: ["utils"], path: "chapter_tree", sources: ["avl_tree.swift"]),
// chapter_heap
.executableTarget(name: "heap", dependencies: ["utils", .product(name: "HeapModule", package: "swift-collections")], path: "chapter_heap", sources: ["heap.swift"]),
.executableTarget(name: "my_heap", dependencies: ["utils"], path: "chapter_heap", sources: ["my_heap.swift"]),
.executableTarget(name: "top_k", dependencies: ["utils", .product(name: "HeapModule", package: "swift-collections")], path: "chapter_heap", sources: ["top_k.swift"]),
// chapter_graph
Expand Down
5 changes: 5 additions & 0 deletions codes/swift/chapter_array_and_linkedlist/array.swift
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ func traverse(nums: [Int]) {
for num in nums {
count += num
}
// 同时遍历数据索引和元素
for (i, num) in nums.enumerated() {
count += nums[i]
count += num
}
}

/* 在数组中查找指定元素 */
Expand Down
1 change: 0 additions & 1 deletion codes/swift/chapter_array_and_linkedlist/linked_list.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ func remove(n0: ListNode) {
let P = n0.next
let n1 = P?.next
n0.next = n1
P?.next = nil
}

/* 访问链表中索引为 index 的节点 */
Expand Down
35 changes: 17 additions & 18 deletions codes/swift/chapter_array_and_linkedlist/my_list.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,15 @@
/* 列表类 */
class MyList {
private var arr: [Int] // 数组(存储列表元素)
private var _capacity = 10 // 列表容量
private var _size = 0 // 列表长度(当前元素数量)
private let extendRatio = 2 // 每次列表扩容的倍数
private var _capacity: Int // 列表容量
private var _size: Int // 列表长度(当前元素数量)
private let extendRatio: Int // 每次列表扩容的倍数

/* 构造方法 */
init() {
_capacity = 10
_size = 0
extendRatio = 2
arr = Array(repeating: 0, count: _capacity)
}

Expand All @@ -29,15 +32,15 @@ class MyList {
/* 访问元素 */
func get(index: Int) -> Int {
// 索引如果越界则抛出错误,下同
if index < 0 || index >= _size {
if index < 0 || index >= size() {
fatalError("索引越界")
}
return arr[index]
}

/* 更新元素 */
func set(index: Int, num: Int) {
if index < 0 || index >= _size {
if index < 0 || index >= size() {
fatalError("索引越界")
}
arr[index] = num
Expand All @@ -46,25 +49,25 @@ class MyList {
/* 在尾部添加元素 */
func add(num: Int) {
// 元素数量超出容量时,触发扩容机制
if _size == _capacity {
if size() == capacity() {
extendCapacity()
}
arr[_size] = num
arr[size()] = num
// 更新元素数量
_size += 1
}

/* 在中间插入元素 */
func insert(index: Int, num: Int) {
if index < 0 || index >= _size {
if index < 0 || index >= size() {
fatalError("索引越界")
}
// 元素数量超出容量时,触发扩容机制
if _size == _capacity {
if size() == capacity() {
extendCapacity()
}
// 将索引 index 以及之后的元素都向后移动一位
for j in sequence(first: _size - 1, next: { $0 >= index + 1 ? $0 - 1 : nil }) {
for j in (index ..< size()).reversed() {
arr[j + 1] = arr[j]
}
arr[index] = num
Expand All @@ -75,12 +78,12 @@ class MyList {
/* 删除元素 */
@discardableResult
func remove(index: Int) -> Int {
if index < 0 || index >= _size {
if index < 0 || index >= size() {
fatalError("索引越界")
}
let num = arr[index]
// 将将索引 index 之后的元素都向前移动一位
for j in index ..< (_size - 1) {
for j in index ..< (size() - 1) {
arr[j] = arr[j + 1]
}
// 更新元素数量
Expand All @@ -92,18 +95,14 @@ class MyList {
/* 列表扩容 */
func extendCapacity() {
// 新建一个长度为原数组 extendRatio 倍的新数组,并将原数组复制到新数组
arr = arr + Array(repeating: 0, count: _capacity * (extendRatio - 1))
arr = arr + Array(repeating: 0, count: capacity() * (extendRatio - 1))
// 更新列表容量
_capacity = arr.count
}

/* 将列表转换为数组 */
func toArray() -> [Int] {
var arr = Array(repeating: 0, count: _size)
for i in 0 ..< _size {
arr[i] = get(index: i)
}
return arr
Array(arr.prefix(size()))
}
}

Expand Down
2 changes: 1 addition & 1 deletion codes/swift/chapter_backtracking/subset_sum_i.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ func backtrack(state: inout [Int], target: Int, choices: [Int], start: Int, res:
}
// 遍历所有选择
// 剪枝二:从 start 开始遍历,避免生成重复子集
for i in stride(from: start, to: choices.count, by: 1) {
for i in choices.indices.dropFirst(start) {
// 剪枝一:若子集和超过 target ,则直接结束循环
// 这是因为数组已排序,后边元素更大,子集和一定超过 target
if target - choices[i] < 0 {
Expand Down
2 changes: 1 addition & 1 deletion codes/swift/chapter_backtracking/subset_sum_i_naive.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ func backtrack(state: inout [Int], target: Int, total: Int, choices: [Int], res:
return
}
// 遍历所有选择
for i in stride(from: 0, to: choices.count, by: 1) {
for i in choices.indices {
// 剪枝:若子集和超过 target ,则跳过该选择
if total + choices[i] > target {
continue
Expand Down
2 changes: 1 addition & 1 deletion codes/swift/chapter_backtracking/subset_sum_ii.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ func backtrack(state: inout [Int], target: Int, choices: [Int], start: Int, res:
// 遍历所有选择
// 剪枝二:从 start 开始遍历,避免生成重复子集
// 剪枝三:从 start 开始遍历,避免重复选择同一元素
for i in stride(from: start, to: choices.count, by: 1) {
for i in choices.indices.dropFirst(start) {
// 剪枝一:若子集和超过 target ,则直接结束循环
// 这是因为数组已排序,后边元素更大,子集和一定超过 target
if target - choices[i] < 0 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func forLoopRecur(n: Int) -> Int {
var stack: [Int] = []
var res = 0
// 递:递归调用
for i in stride(from: n, to: 0, by: -1) {
for i in (1 ... n).reversed() {
// 通过“入栈操作”模拟“递”
stack.append(i)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func quadratic(n: Int) -> Int {
func bubbleSort(nums: inout [Int]) -> Int {
var count = 0 // 计数器
// 外循环:未排序区间为 [0, i]
for i in stride(from: nums.count - 1, to: 0, by: -1) {
for i in nums.indices.dropFirst().reversed() {
// 内循环:将未排序区间 [0, i] 中的最大元素交换至该区间的最右端
for j in 0 ..< i {
if nums[j] > nums[j + 1] {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,8 @@ func dfs(nums: [Int], target: Int, i: Int, j: Int) -> Int {

/* 二分查找 */
func binarySearch(nums: [Int], target: Int) -> Int {
let n = nums.count
// 求解问题 f(0, n-1)
return dfs(nums: nums, target: target, i: 0, j: n - 1)
dfs(nums: nums, target: target, i: nums.startIndex, j: nums.endIndex - 1)
}

@main
Expand Down
2 changes: 1 addition & 1 deletion codes/swift/chapter_divide_and_conquer/build_tree.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func dfs(preorder: [Int], inorderMap: [Int: Int], i: Int, l: Int, r: Int) -> Tre
func buildTree(preorder: [Int], inorder: [Int]) -> TreeNode? {
// 初始化哈希表,存储 inorder 元素到索引的映射
let inorderMap = inorder.enumerated().reduce(into: [:]) { $0[$1.element] = $1.offset }
return dfs(preorder: preorder, inorderMap: inorderMap, i: 0, l: 0, r: inorder.count - 1)
return dfs(preorder: preorder, inorderMap: inorderMap, i: inorder.startIndex, l: inorder.startIndex, r: inorder.endIndex - 1)
}

@main
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ func climbingStairsConstraintDP(n: Int) -> Int {
dp[2][1] = 0
dp[2][2] = 1
// 状态转移:从较小子问题逐步求解较大子问题
for i in stride(from: 3, through: n, by: 1) {
for i in 3 ... n {
dp[i][1] = dp[i - 1][2]
dp[i][2] = dp[i - 2][1] + dp[i - 2][2]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func climbingStairsDP(n: Int) -> Int {
dp[1] = 1
dp[2] = 2
// 状态转移:从较小子问题逐步求解较大子问题
for i in stride(from: 3, through: n, by: 1) {
for i in 3 ... n {
dp[i] = dp[i - 1] + dp[i - 2]
}
return dp[n]
Expand All @@ -28,7 +28,7 @@ func climbingStairsDPComp(n: Int) -> Int {
}
var a = 1
var b = 2
for _ in stride(from: 3, through: n, by: 1) {
for _ in 3 ... n {
(a, b) = (b, a + b)
}
return b
Expand Down
10 changes: 5 additions & 5 deletions codes/swift/chapter_dynamic_programming/coin_change.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ func coinChangeDP(coins: [Int], amt: Int) -> Int {
// 初始化 dp 表
var dp = Array(repeating: Array(repeating: 0, count: amt + 1), count: n + 1)
// 状态转移:首行首列
for a in stride(from: 1, through: amt, by: 1) {
for a in 1 ... amt {
dp[0][a] = MAX
}
// 状态转移:其余行和列
for i in stride(from: 1, through: n, by: 1) {
for a in stride(from: 1, through: amt, by: 1) {
for i in 1 ... n {
for a in 1 ... amt {
if coins[i - 1] > a {
// 若超过目标金额,则不选硬币 i
dp[i][a] = dp[i - 1][a]
Expand All @@ -37,8 +37,8 @@ func coinChangeDPComp(coins: [Int], amt: Int) -> Int {
var dp = Array(repeating: MAX, count: amt + 1)
dp[0] = 0
// 状态转移
for i in stride(from: 1, through: n, by: 1) {
for a in stride(from: 1, through: amt, by: 1) {
for i in 1 ... n {
for a in 1 ... amt {
if coins[i - 1] > a {
// 若超过目标金额,则不选硬币 i
dp[a] = dp[a]
Expand Down
10 changes: 5 additions & 5 deletions codes/swift/chapter_dynamic_programming/coin_change_ii.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ func coinChangeIIDP(coins: [Int], amt: Int) -> Int {
// 初始化 dp 表
var dp = Array(repeating: Array(repeating: 0, count: amt + 1), count: n + 1)
// 初始化首列
for i in stride(from: 0, through: n, by: 1) {
for i in 0 ... n {
dp[i][0] = 1
}
// 状态转移
for i in stride(from: 1, through: n, by: 1) {
for a in stride(from: 1, through: amt, by: 1) {
for i in 1 ... n {
for a in 1 ... amt {
if coins[i - 1] > a {
// 若超过目标金额,则不选硬币 i
dp[i][a] = dp[i - 1][a]
Expand All @@ -35,8 +35,8 @@ func coinChangeIIDPComp(coins: [Int], amt: Int) -> Int {
var dp = Array(repeating: 0, count: amt + 1)
dp[0] = 1
// 状态转移
for i in stride(from: 1, through: n, by: 1) {
for a in stride(from: 1, through: amt, by: 1) {
for i in 1 ... n {
for a in 1 ... amt {
if coins[i - 1] > a {
// 若超过目标金额,则不选硬币 i
dp[a] = dp[a]
Expand Down
14 changes: 7 additions & 7 deletions codes/swift/chapter_dynamic_programming/edit_distance.swift
Original file line number Diff line number Diff line change
Expand Up @@ -67,15 +67,15 @@ func editDistanceDP(s: String, t: String) -> Int {
let m = t.utf8CString.count
var dp = Array(repeating: Array(repeating: 0, count: m + 1), count: n + 1)
// 状态转移:首行首列
for i in stride(from: 1, through: n, by: 1) {
for i in 1 ... n {
dp[i][0] = i
}
for j in stride(from: 1, through: m, by: 1) {
for j in 1 ... m {
dp[0][j] = j
}
// 状态转移:其余行和列
for i in stride(from: 1, through: n, by: 1) {
for j in stride(from: 1, through: m, by: 1) {
for i in 1 ... n {
for j in 1 ... m {
if s.utf8CString[i - 1] == t.utf8CString[j - 1] {
// 若两字符相等,则直接跳过此两字符
dp[i][j] = dp[i - 1][j - 1]
Expand All @@ -94,16 +94,16 @@ func editDistanceDPComp(s: String, t: String) -> Int {
let m = t.utf8CString.count
var dp = Array(repeating: 0, count: m + 1)
// 状态转移:首行
for j in stride(from: 1, through: m, by: 1) {
for j in 1 ... m {
dp[j] = j
}
// 状态转移:其余行
for i in stride(from: 1, through: n, by: 1) {
for i in 1 ... n {
// 状态转移:首列
var leftup = dp[0] // 暂存 dp[i-1, j-1]
dp[0] = i
// 状态转移:其余列
for j in stride(from: 1, through: m, by: 1) {
for j in 1 ... m {
let temp = dp[j]
if s.utf8CString[i - 1] == t.utf8CString[j - 1] {
// 若两字符相等,则直接跳过此两字符
Expand Down
8 changes: 4 additions & 4 deletions codes/swift/chapter_dynamic_programming/knapsack.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ func knapsackDP(wgt: [Int], val: [Int], cap: Int) -> Int {
// 初始化 dp 表
var dp = Array(repeating: Array(repeating: 0, count: cap + 1), count: n + 1)
// 状态转移
for i in stride(from: 1, through: n, by: 1) {
for c in stride(from: 1, through: cap, by: 1) {
for i in 1 ... n {
for c in 1 ... cap {
if wgt[i - 1] > c {
// 若超过背包容量,则不选物品 i
dp[i][c] = dp[i - 1][c]
Expand All @@ -69,9 +69,9 @@ func knapsackDPComp(wgt: [Int], val: [Int], cap: Int) -> Int {
// 初始化 dp 表
var dp = Array(repeating: 0, count: cap + 1)
// 状态转移
for i in stride(from: 1, through: n, by: 1) {
for i in 1 ... n {
// 倒序遍历
for c in stride(from: cap, through: 1, by: -1) {
for c in (1 ... cap).reversed() {
if wgt[i - 1] <= c {
// 不选和选物品 i 这两种方案的较大值
dp[c] = max(dp[c], dp[c - wgt[i - 1]] + val[i - 1])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ func minCostClimbingStairsDP(cost: [Int]) -> Int {
dp[1] = cost[1]
dp[2] = cost[2]
// 状态转移:从较小子问题逐步求解较大子问题
for i in stride(from: 3, through: n, by: 1) {
for i in 3 ... n {
dp[i] = min(dp[i - 1], dp[i - 2]) + cost[i]
}
return dp[n]
Expand All @@ -29,7 +29,7 @@ func minCostClimbingStairsDPComp(cost: [Int]) -> Int {
return cost[n]
}
var (a, b) = (cost[1], cost[2])
for i in stride(from: 3, through: n, by: 1) {
for i in 3 ... n {
(a, b) = (b, min(a, b) + cost[i])
}
return b
Expand Down
Loading

0 comments on commit 7359a7c

Please sign in to comment.