Review Swift codes (#1150)

* 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
This commit is contained in:
nuomi1 2024-03-20 21:15:39 +08:00 committed by GitHub
parent 300a781fab
commit 7359a7cb4b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
55 changed files with 293 additions and 224 deletions

View File

@ -19,9 +19,9 @@ jobs:
strategy: strategy:
matrix: matrix:
os: [ubuntu-latest, macos-latest] os: [ubuntu-latest, macos-latest]
swift: ["5.9", "5.8.1", "5.7.3"] swift: ["5.10", "5.9", "5.8"]
steps: steps:
- uses: swift-actions/setup-swift@v1 - uses: swift-actions/setup-swift@v2
with: with:
swift-version: ${{ matrix.swift }} swift-version: ${{ matrix.swift }}
- uses: actions/checkout@v4 - uses: actions/checkout@v4

View File

@ -41,6 +41,7 @@ let package = Package(
.executable(name: "binary_search_tree", targets: ["binary_search_tree"]), .executable(name: "binary_search_tree", targets: ["binary_search_tree"]),
.executable(name: "avl_tree", targets: ["avl_tree"]), .executable(name: "avl_tree", targets: ["avl_tree"]),
// chapter_heap // chapter_heap
.executable(name: "heap", targets: ["heap"]),
.executable(name: "my_heap", targets: ["my_heap"]), .executable(name: "my_heap", targets: ["my_heap"]),
.executable(name: "top_k", targets: ["top_k"]), .executable(name: "top_k", targets: ["top_k"]),
// chapter_graph // chapter_graph
@ -143,6 +144,7 @@ let package = Package(
.executableTarget(name: "binary_search_tree", dependencies: ["utils"], path: "chapter_tree", sources: ["binary_search_tree.swift"]), .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"]), .executableTarget(name: "avl_tree", dependencies: ["utils"], path: "chapter_tree", sources: ["avl_tree.swift"]),
// chapter_heap // 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: "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"]), .executableTarget(name: "top_k", dependencies: ["utils", .product(name: "HeapModule", package: "swift-collections")], path: "chapter_heap", sources: ["top_k.swift"]),
// chapter_graph // chapter_graph

View File

@ -54,6 +54,11 @@ func traverse(nums: [Int]) {
for num in nums { for num in nums {
count += num count += num
} }
//
for (i, num) in nums.enumerated() {
count += nums[i]
count += num
}
} }
/* */ /* */

View File

@ -22,7 +22,6 @@ func remove(n0: ListNode) {
let P = n0.next let P = n0.next
let n1 = P?.next let n1 = P?.next
n0.next = n1 n0.next = n1
P?.next = nil
} }
/* 访 index */ /* 访 index */

View File

@ -7,12 +7,15 @@
/* */ /* */
class MyList { class MyList {
private var arr: [Int] // private var arr: [Int] //
private var _capacity = 10 // private var _capacity: Int //
private var _size = 0 // private var _size: Int //
private let extendRatio = 2 // private let extendRatio: Int //
/* */ /* */
init() { init() {
_capacity = 10
_size = 0
extendRatio = 2
arr = Array(repeating: 0, count: _capacity) arr = Array(repeating: 0, count: _capacity)
} }
@ -29,7 +32,7 @@ class MyList {
/* 访 */ /* 访 */
func get(index: Int) -> Int { func get(index: Int) -> Int {
// //
if index < 0 || index >= _size { if index < 0 || index >= size() {
fatalError("索引越界") fatalError("索引越界")
} }
return arr[index] return arr[index]
@ -37,7 +40,7 @@ class MyList {
/* */ /* */
func set(index: Int, num: Int) { func set(index: Int, num: Int) {
if index < 0 || index >= _size { if index < 0 || index >= size() {
fatalError("索引越界") fatalError("索引越界")
} }
arr[index] = num arr[index] = num
@ -46,25 +49,25 @@ class MyList {
/* */ /* */
func add(num: Int) { func add(num: Int) {
// //
if _size == _capacity { if size() == capacity() {
extendCapacity() extendCapacity()
} }
arr[_size] = num arr[size()] = num
// //
_size += 1 _size += 1
} }
/* */ /* */
func insert(index: Int, num: Int) { func insert(index: Int, num: Int) {
if index < 0 || index >= _size { if index < 0 || index >= size() {
fatalError("索引越界") fatalError("索引越界")
} }
// //
if _size == _capacity { if size() == capacity() {
extendCapacity() extendCapacity()
} }
// index // 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[j + 1] = arr[j]
} }
arr[index] = num arr[index] = num
@ -75,12 +78,12 @@ class MyList {
/* */ /* */
@discardableResult @discardableResult
func remove(index: Int) -> Int { func remove(index: Int) -> Int {
if index < 0 || index >= _size { if index < 0 || index >= size() {
fatalError("索引越界") fatalError("索引越界")
} }
let num = arr[index] let num = arr[index]
// index // index
for j in index ..< (_size - 1) { for j in index ..< (size() - 1) {
arr[j] = arr[j + 1] arr[j] = arr[j + 1]
} }
// //
@ -92,18 +95,14 @@ class MyList {
/* */ /* */
func extendCapacity() { func extendCapacity() {
// extendRatio // extendRatio
arr = arr + Array(repeating: 0, count: _capacity * (extendRatio - 1)) arr = arr + Array(repeating: 0, count: capacity() * (extendRatio - 1))
// //
_capacity = arr.count _capacity = arr.count
} }
/* */ /* */
func toArray() -> [Int] { func toArray() -> [Int] {
var arr = Array(repeating: 0, count: _size) Array(arr.prefix(size()))
for i in 0 ..< _size {
arr[i] = get(index: i)
}
return arr
} }
} }

View File

@ -13,7 +13,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
// target // target
if target - choices[i] < 0 { if target - choices[i] < 0 {

View File

@ -12,7 +12,7 @@ func backtrack(state: inout [Int], target: Int, total: Int, choices: [Int], res:
return return
} }
// //
for i in stride(from: 0, to: choices.count, by: 1) { for i in choices.indices {
// target // target
if total + choices[i] > target { if total + choices[i] > target {
continue continue

View File

@ -14,7 +14,7 @@ func backtrack(state: inout [Int], target: Int, choices: [Int], start: Int, res:
// //
// start // start
// start // start
for i in stride(from: start, to: choices.count, by: 1) { for i in choices.indices.dropFirst(start) {
// target // target
// target // target
if target - choices[i] < 0 { if target - choices[i] < 0 {

View File

@ -22,7 +22,7 @@ func forLoopRecur(n: Int) -> Int {
var stack: [Int] = [] var stack: [Int] = []
var res = 0 var res = 0
// //
for i in stride(from: n, to: 0, by: -1) { for i in (1 ... n).reversed() {
// //
stack.append(i) stack.append(i)
} }

View File

@ -49,7 +49,7 @@ func quadratic(n: Int) -> Int {
func bubbleSort(nums: inout [Int]) -> Int { func bubbleSort(nums: inout [Int]) -> Int {
var count = 0 // var count = 0 //
// [0, i] // [0, i]
for i in stride(from: nums.count - 1, to: 0, by: -1) { for i in nums.indices.dropFirst().reversed() {
// [0, i] // [0, i]
for j in 0 ..< i { for j in 0 ..< i {
if nums[j] > nums[j + 1] { if nums[j] > nums[j + 1] {

View File

@ -26,9 +26,8 @@ func dfs(nums: [Int], target: Int, i: Int, j: Int) -> Int {
/* */ /* */
func binarySearch(nums: [Int], target: Int) -> Int { func binarySearch(nums: [Int], target: Int) -> Int {
let n = nums.count
// f(0, n-1) // 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 @main

View File

@ -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? { func buildTree(preorder: [Int], inorder: [Int]) -> TreeNode? {
// inorder // inorder
let inorderMap = inorder.enumerated().reduce(into: [:]) { $0[$1.element] = $1.offset } 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 @main

View File

@ -17,7 +17,7 @@ func climbingStairsConstraintDP(n: Int) -> Int {
dp[2][1] = 0 dp[2][1] = 0
dp[2][2] = 1 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][1] = dp[i - 1][2]
dp[i][2] = dp[i - 2][1] + dp[i - 2][2] dp[i][2] = dp[i - 2][1] + dp[i - 2][2]
} }

View File

@ -15,7 +15,7 @@ func climbingStairsDP(n: Int) -> Int {
dp[1] = 1 dp[1] = 1
dp[2] = 2 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] dp[i] = dp[i - 1] + dp[i - 2]
} }
return dp[n] return dp[n]
@ -28,7 +28,7 @@ func climbingStairsDPComp(n: Int) -> Int {
} }
var a = 1 var a = 1
var b = 2 var b = 2
for _ in stride(from: 3, through: n, by: 1) { for _ in 3 ... n {
(a, b) = (b, a + b) (a, b) = (b, a + b)
} }
return b return b

View File

@ -11,12 +11,12 @@ func coinChangeDP(coins: [Int], amt: Int) -> Int {
// dp // dp
var dp = Array(repeating: Array(repeating: 0, count: amt + 1), count: n + 1) 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 dp[0][a] = MAX
} }
// //
for i in stride(from: 1, through: n, by: 1) { for i in 1 ... n {
for a in stride(from: 1, through: amt, by: 1) { for a in 1 ... amt {
if coins[i - 1] > a { if coins[i - 1] > a {
// i // i
dp[i][a] = dp[i - 1][a] dp[i][a] = dp[i - 1][a]
@ -37,8 +37,8 @@ func coinChangeDPComp(coins: [Int], amt: Int) -> Int {
var dp = Array(repeating: MAX, count: amt + 1) var dp = Array(repeating: MAX, count: amt + 1)
dp[0] = 0 dp[0] = 0
// //
for i in stride(from: 1, through: n, by: 1) { for i in 1 ... n {
for a in stride(from: 1, through: amt, by: 1) { for a in 1 ... amt {
if coins[i - 1] > a { if coins[i - 1] > a {
// i // i
dp[a] = dp[a] dp[a] = dp[a]

View File

@ -10,12 +10,12 @@ func coinChangeIIDP(coins: [Int], amt: Int) -> Int {
// dp // dp
var dp = Array(repeating: Array(repeating: 0, count: amt + 1), count: n + 1) 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 dp[i][0] = 1
} }
// //
for i in stride(from: 1, through: n, by: 1) { for i in 1 ... n {
for a in stride(from: 1, through: amt, by: 1) { for a in 1 ... amt {
if coins[i - 1] > a { if coins[i - 1] > a {
// i // i
dp[i][a] = dp[i - 1][a] dp[i][a] = dp[i - 1][a]
@ -35,8 +35,8 @@ func coinChangeIIDPComp(coins: [Int], amt: Int) -> Int {
var dp = Array(repeating: 0, count: amt + 1) var dp = Array(repeating: 0, count: amt + 1)
dp[0] = 1 dp[0] = 1
// //
for i in stride(from: 1, through: n, by: 1) { for i in 1 ... n {
for a in stride(from: 1, through: amt, by: 1) { for a in 1 ... amt {
if coins[i - 1] > a { if coins[i - 1] > a {
// i // i
dp[a] = dp[a] dp[a] = dp[a]

View File

@ -67,15 +67,15 @@ func editDistanceDP(s: String, t: String) -> Int {
let m = t.utf8CString.count let m = t.utf8CString.count
var dp = Array(repeating: Array(repeating: 0, count: m + 1), count: n + 1) 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 dp[i][0] = i
} }
for j in stride(from: 1, through: m, by: 1) { for j in 1 ... m {
dp[0][j] = j dp[0][j] = j
} }
// //
for i in stride(from: 1, through: n, by: 1) { for i in 1 ... n {
for j in stride(from: 1, through: m, by: 1) { for j in 1 ... m {
if s.utf8CString[i - 1] == t.utf8CString[j - 1] { if s.utf8CString[i - 1] == t.utf8CString[j - 1] {
// //
dp[i][j] = dp[i - 1][j - 1] dp[i][j] = dp[i - 1][j - 1]
@ -94,16 +94,16 @@ func editDistanceDPComp(s: String, t: String) -> Int {
let m = t.utf8CString.count let m = t.utf8CString.count
var dp = Array(repeating: 0, count: m + 1) 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 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] var leftup = dp[0] // dp[i-1, j-1]
dp[0] = i dp[0] = i
// //
for j in stride(from: 1, through: m, by: 1) { for j in 1 ... m {
let temp = dp[j] let temp = dp[j]
if s.utf8CString[i - 1] == t.utf8CString[j - 1] { if s.utf8CString[i - 1] == t.utf8CString[j - 1] {
// //

View File

@ -49,8 +49,8 @@ func knapsackDP(wgt: [Int], val: [Int], cap: Int) -> Int {
// dp // dp
var dp = Array(repeating: Array(repeating: 0, count: cap + 1), count: n + 1) var dp = Array(repeating: Array(repeating: 0, count: cap + 1), count: n + 1)
// //
for i in stride(from: 1, through: n, by: 1) { for i in 1 ... n {
for c in stride(from: 1, through: cap, by: 1) { for c in 1 ... cap {
if wgt[i - 1] > c { if wgt[i - 1] > c {
// i // i
dp[i][c] = dp[i - 1][c] dp[i][c] = dp[i - 1][c]
@ -69,9 +69,9 @@ func knapsackDPComp(wgt: [Int], val: [Int], cap: Int) -> Int {
// dp // dp
var dp = Array(repeating: 0, count: cap + 1) 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 { if wgt[i - 1] <= c {
// i // i
dp[c] = max(dp[c], dp[c - wgt[i - 1]] + val[i - 1]) dp[c] = max(dp[c], dp[c - wgt[i - 1]] + val[i - 1])

View File

@ -16,7 +16,7 @@ func minCostClimbingStairsDP(cost: [Int]) -> Int {
dp[1] = cost[1] dp[1] = cost[1]
dp[2] = cost[2] 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] dp[i] = min(dp[i - 1], dp[i - 2]) + cost[i]
} }
return dp[n] return dp[n]
@ -29,7 +29,7 @@ func minCostClimbingStairsDPComp(cost: [Int]) -> Int {
return cost[n] return cost[n]
} }
var (a, b) = (cost[1], cost[2]) 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]) (a, b) = (b, min(a, b) + cost[i])
} }
return b return b

View File

@ -51,16 +51,16 @@ func minPathSumDP(grid: [[Int]]) -> Int {
var dp = Array(repeating: Array(repeating: 0, count: m), count: n) var dp = Array(repeating: Array(repeating: 0, count: m), count: n)
dp[0][0] = grid[0][0] dp[0][0] = grid[0][0]
// //
for j in stride(from: 1, to: m, by: 1) { for j in 1 ..< m {
dp[0][j] = dp[0][j - 1] + grid[0][j] dp[0][j] = dp[0][j - 1] + grid[0][j]
} }
// //
for i in stride(from: 1, to: n, by: 1) { for i in 1 ..< n {
dp[i][0] = dp[i - 1][0] + grid[i][0] dp[i][0] = dp[i - 1][0] + grid[i][0]
} }
// //
for i in stride(from: 1, to: n, by: 1) { for i in 1 ..< n {
for j in stride(from: 1, to: m, by: 1) { for j in 1 ..< m {
dp[i][j] = min(dp[i][j - 1], dp[i - 1][j]) + grid[i][j] dp[i][j] = min(dp[i][j - 1], dp[i - 1][j]) + grid[i][j]
} }
} }
@ -75,15 +75,15 @@ func minPathSumDPComp(grid: [[Int]]) -> Int {
var dp = Array(repeating: 0, count: m) var dp = Array(repeating: 0, count: m)
// //
dp[0] = grid[0][0] dp[0] = grid[0][0]
for j in stride(from: 1, to: m, by: 1) { for j in 1 ..< m {
dp[j] = dp[j - 1] + grid[0][j] dp[j] = dp[j - 1] + grid[0][j]
} }
// //
for i in stride(from: 1, to: n, by: 1) { for i in 1 ..< n {
// //
dp[0] = dp[0] + grid[i][0] dp[0] = dp[0] + grid[i][0]
// //
for j in stride(from: 1, to: m, by: 1) { for j in 1 ..< m {
dp[j] = min(dp[j - 1], dp[j]) + grid[i][j] dp[j] = min(dp[j - 1], dp[j]) + grid[i][j]
} }
} }

View File

@ -10,8 +10,8 @@ func unboundedKnapsackDP(wgt: [Int], val: [Int], cap: Int) -> Int {
// dp // dp
var dp = Array(repeating: Array(repeating: 0, count: cap + 1), count: n + 1) var dp = Array(repeating: Array(repeating: 0, count: cap + 1), count: n + 1)
// //
for i in stride(from: 1, through: n, by: 1) { for i in 1 ... n {
for c in stride(from: 1, through: cap, by: 1) { for c in 1 ... cap {
if wgt[i - 1] > c { if wgt[i - 1] > c {
// i // i
dp[i][c] = dp[i - 1][c] dp[i][c] = dp[i - 1][c]
@ -30,8 +30,8 @@ func unboundedKnapsackDPComp(wgt: [Int], val: [Int], cap: Int) -> Int {
// dp // dp
var dp = Array(repeating: 0, count: cap + 1) 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: 1, through: cap, by: 1) { for c in 1 ... cap {
if wgt[i - 1] > c { if wgt[i - 1] > c {
// i // i
dp[c] = dp[c] dp[c] = dp[c]

View File

@ -43,8 +43,8 @@ public class GraphAdjList {
fatalError("参数错误") fatalError("参数错误")
} }
// vet1 - vet2 // vet1 - vet2
adjList[vet1]?.removeAll(where: { $0 == vet2 }) adjList[vet1]?.removeAll { $0 == vet2 }
adjList[vet2]?.removeAll(where: { $0 == vet1 }) adjList[vet2]?.removeAll { $0 == vet1 }
} }
/* */ /* */
@ -65,19 +65,16 @@ public class GraphAdjList {
adjList.removeValue(forKey: vet) adjList.removeValue(forKey: vet)
// vet // vet
for key in adjList.keys { for key in adjList.keys {
adjList[key]?.removeAll(where: { $0 == vet }) adjList[key]?.removeAll { $0 == vet }
} }
} }
/* */ /* */
public func print() { public func print() {
Swift.print("邻接表 =") Swift.print("邻接表 =")
for pair in adjList { for (vertex, list) in adjList {
var tmp: [Int] = [] let list = list.map { $0.val }
for vertex in pair.value { Swift.print("\(vertex.val): \(list),")
tmp.append(vertex.val)
}
Swift.print("\(pair.key.val): \(tmp),")
} }
} }
} }

View File

@ -20,7 +20,7 @@ func fractionalKnapsack(wgt: [Int], val: [Int], cap: Int) -> Double {
// //
var items = zip(wgt, val).map { Item(w: $0, v: $1) } var items = zip(wgt, val).map { Item(w: $0, v: $1) }
// item.v / item.w // item.v / item.w
items.sort(by: { -(Double($0.v) / Double($0.w)) < -(Double($1.v) / Double($1.w)) }) items.sort { -(Double($0.v) / Double($0.w)) < -(Double($1.v) / Double($1.w)) }
// //
var res = 0.0 var res = 0.0
var cap = cap var cap = cap

View File

@ -7,7 +7,7 @@
/* */ /* */
func maxCapacity(ht: [Int]) -> Int { func maxCapacity(ht: [Int]) -> Int {
// i, j使 // i, j使
var i = 0, j = ht.count - 1 var i = ht.startIndex, j = ht.endIndex - 1
// 0 // 0
var res = 0 var res = 0
// //

View File

@ -8,13 +8,11 @@ import utils
/* */ /* */
class ArrayHashMap { class ArrayHashMap {
private var buckets: [Pair?] = [] private var buckets: [Pair?]
init() { init() {
// 100 // 100
for _ in 0 ..< 100 { buckets = Array(repeating: nil, count: 100)
buckets.append(nil)
}
} }
/* */ /* */
@ -46,35 +44,17 @@ class ArrayHashMap {
/* */ /* */
func pairSet() -> [Pair] { func pairSet() -> [Pair] {
var pairSet: [Pair] = [] buckets.compactMap { $0 }
for pair in buckets {
if let pair = pair {
pairSet.append(pair)
}
}
return pairSet
} }
/* */ /* */
func keySet() -> [Int] { func keySet() -> [Int] {
var keySet: [Int] = [] buckets.compactMap { $0?.key }
for pair in buckets {
if let pair = pair {
keySet.append(pair.key)
}
}
return keySet
} }
/* */ /* */
func valueSet() -> [String] { func valueSet() -> [String] {
var valueSet: [String] = [] buckets.compactMap { $0?.val }
for pair in buckets {
if let pair = pair {
valueSet.append(pair.val)
}
}
return valueSet
} }
/* */ /* */

View File

@ -30,7 +30,7 @@ class HashMapChaining {
/* */ /* */
func loadFactor() -> Double { func loadFactor() -> Double {
Double(size / capacity) Double(size) / Double(capacity)
} }
/* */ /* */
@ -76,9 +76,10 @@ class HashMapChaining {
for (pairIndex, pair) in bucket.enumerated() { for (pairIndex, pair) in bucket.enumerated() {
if pair.key == key { if pair.key == key {
buckets[index].remove(at: pairIndex) buckets[index].remove(at: pairIndex)
size -= 1
break
} }
} }
size -= 1
} }
/* */ /* */

View File

@ -32,7 +32,7 @@ class HashMapOpenAddressing {
/* */ /* */
func loadFactor() -> Double { func loadFactor() -> Double {
Double(size / capacity) Double(size) / Double(capacity)
} }
/* key */ /* key */

View File

@ -0,0 +1,62 @@
/**
* File: heap.swift
* Created Time: 2024-03-17
* Author: nuomi1 (nuomi1@qq.com)
*/
import HeapModule
import utils
func testPush(heap: inout Heap<Int>, val: Int) {
heap.insert(val)
print("\n元素 \(val) 入堆后\n")
PrintUtil.printHeap(queue: heap.unordered)
}
func testPop(heap: inout Heap<Int>) {
let val = heap.removeMax()
print("\n堆顶元素 \(val) 出堆后\n")
PrintUtil.printHeap(queue: heap.unordered)
}
@main
enum _Heap {
/* Driver Code */
static func main() {
/* */
// Swift Heap
var heap = Heap<Int>()
/* */
testPush(heap: &heap, val: 1)
testPush(heap: &heap, val: 3)
testPush(heap: &heap, val: 2)
testPush(heap: &heap, val: 5)
testPush(heap: &heap, val: 4)
/* */
let peek = heap.max()
print("\n堆顶元素为 \(peek!)\n")
/* */
testPop(heap: &heap)
testPop(heap: &heap)
testPop(heap: &heap)
testPop(heap: &heap)
testPop(heap: &heap)
/* */
let size = heap.count
print("\n堆元素数量为 \(size)\n")
/* */
let isEmpty = heap.isEmpty
print("\n堆是否为空 \(isEmpty)\n")
/* */
// O(n) O(nlogn)
let heap2 = Heap([1, 3, 2, 5, 4])
print("\n输入列表并建立堆后")
PrintUtil.printHeap(queue: heap2.unordered)
}
}

View File

@ -15,7 +15,7 @@ class MaxHeap {
// //
maxHeap = nums maxHeap = nums
// //
for i in stride(from: parent(i: size() - 1), through: 0, by: -1) { for i in (0 ... parent(i: size() - 1)).reversed() {
siftDown(i: i) siftDown(i: i)
} }
} }

View File

@ -12,7 +12,7 @@ func topKHeap(nums: [Int], k: Int) -> [Int] {
// k // k
var heap = Heap(nums.prefix(k)) var heap = Heap(nums.prefix(k))
// k+1 k // k+1 k
for i in stride(from: k, to: nums.count, by: 1) { for i in nums.indices.dropFirst(k) {
// //
if nums[i] > heap.min()! { if nums[i] > heap.min()! {
_ = heap.removeMin() _ = heap.removeMin()

View File

@ -7,8 +7,8 @@
/* */ /* */
func binarySearch(nums: [Int], target: Int) -> Int { func binarySearch(nums: [Int], target: Int) -> Int {
// [0, n-1] i, j // [0, n-1] i, j
var i = 0 var i = nums.startIndex
var j = nums.count - 1 var j = nums.endIndex - 1
// i > j // i > j
while i <= j { while i <= j {
let m = i + (j - i) / 2 // m let m = i + (j - i) / 2 // m
@ -27,8 +27,8 @@ func binarySearch(nums: [Int], target: Int) -> Int {
/* */ /* */
func binarySearchLCRO(nums: [Int], target: Int) -> Int { func binarySearchLCRO(nums: [Int], target: Int) -> Int {
// [0, n) i, j +1 // [0, n) i, j +1
var i = 0 var i = nums.startIndex
var j = nums.count var j = nums.endIndex
// i = j // i = j
while i < j { while i < j {
let m = i + (j - i) / 2 // m let m = i + (j - i) / 2 // m

View File

@ -11,7 +11,7 @@ func binarySearchLeftEdge(nums: [Int], target: Int) -> Int {
// target // target
let i = binarySearchInsertion(nums: nums, target: target) let i = binarySearchInsertion(nums: nums, target: target)
// target -1 // target -1
if i == nums.count || nums[i] != target { if i == nums.endIndex || nums[i] != target {
return -1 return -1
} }
// target i // target i

View File

@ -6,7 +6,9 @@
/* */ /* */
func binarySearchInsertionSimple(nums: [Int], target: Int) -> Int { func binarySearchInsertionSimple(nums: [Int], target: Int) -> Int {
var i = 0, j = nums.count - 1 // [0, n-1] // [0, n-1]
var i = nums.startIndex
var j = nums.endIndex - 1
while i <= j { while i <= j {
let m = i + (j - i) / 2 // m let m = i + (j - i) / 2 // m
if nums[m] < target { if nums[m] < target {
@ -23,7 +25,9 @@ func binarySearchInsertionSimple(nums: [Int], target: Int) -> Int {
/* */ /* */
public func binarySearchInsertion(nums: [Int], target: Int) -> Int { public func binarySearchInsertion(nums: [Int], target: Int) -> Int {
var i = 0, j = nums.count - 1 // [0, n-1] // [0, n-1]
var i = nums.startIndex
var j = nums.endIndex - 1
while i <= j { while i <= j {
let m = i + (j - i) / 2 // m let m = i + (j - i) / 2 // m
if nums[m] < target { if nums[m] < target {

View File

@ -7,14 +7,12 @@
/* */ /* */
func bubbleSort(nums: inout [Int]) { func bubbleSort(nums: inout [Int]) {
// [0, i] // [0, i]
for i in stride(from: nums.count - 1, to: 0, by: -1) { for i in nums.indices.dropFirst().reversed() {
// [0, i] // [0, i]
for j in stride(from: 0, to: i, by: 1) { for j in 0 ..< i {
if nums[j] > nums[j + 1] { if nums[j] > nums[j + 1] {
// nums[j] nums[j + 1] // nums[j] nums[j + 1]
let tmp = nums[j] nums.swapAt(j, j + 1)
nums[j] = nums[j + 1]
nums[j + 1] = tmp
} }
} }
} }
@ -23,14 +21,12 @@ func bubbleSort(nums: inout [Int]) {
/* */ /* */
func bubbleSortWithFlag(nums: inout [Int]) { func bubbleSortWithFlag(nums: inout [Int]) {
// [0, i] // [0, i]
for i in stride(from: nums.count - 1, to: 0, by: -1) { for i in nums.indices.dropFirst().reversed() {
var flag = false // var flag = false //
for j in stride(from: 0, to: i, by: 1) { for j in 0 ..< i {
if nums[j] > nums[j + 1] { if nums[j] > nums[j + 1] {
// nums[j] nums[j + 1] // nums[j] nums[j + 1]
let tmp = nums[j] nums.swapAt(j, j + 1)
nums[j] = nums[j + 1]
nums[j + 1] = tmp
flag = true // flag = true //
} }
} }

View File

@ -26,7 +26,7 @@ func bucketSort(nums: inout [Double]) {
for bucket in buckets { for bucket in buckets {
for num in bucket { for num in bucket {
nums[i] = num nums[i] = num
nums.formIndex(after: &i) i += 1
} }
} }
} }

View File

@ -17,8 +17,8 @@ func countingSortNaive(nums: inout [Int]) {
} }
// 3. counter nums // 3. counter nums
var i = 0 var i = 0
for num in stride(from: 0, to: m + 1, by: 1) { for num in 0 ..< m + 1 {
for _ in stride(from: 0, to: counter[num], by: 1) { for _ in 0 ..< counter[num] {
nums[i] = num nums[i] = num
i += 1 i += 1
} }
@ -38,19 +38,19 @@ func countingSort(nums: inout [Int]) {
} }
// 3. counter // 3. counter
// counter[num]-1 num res // counter[num]-1 num res
for i in stride(from: 0, to: m, by: 1) { for i in 0 ..< m {
counter[i + 1] += counter[i] counter[i + 1] += counter[i]
} }
// 4. nums res // 4. nums res
// res // res
var res = Array(repeating: 0, count: nums.count) var res = Array(repeating: 0, count: nums.count)
for i in stride(from: nums.count - 1, through: 0, by: -1) { for i in nums.indices.reversed() {
let num = nums[i] let num = nums[i]
res[counter[num] - 1] = num // num res[counter[num] - 1] = num // num
counter[num] -= 1 // 1 num counter[num] -= 1 // 1 num
} }
// 使 res nums // 使 res nums
for i in stride(from: 0, to: nums.count, by: 1) { for i in nums.indices {
nums[i] = res[i] nums[i] = res[i]
} }
} }

View File

@ -36,7 +36,7 @@ func heapSort(nums: inout [Int]) {
siftDown(nums: &nums, n: nums.count, i: i) siftDown(nums: &nums, n: nums.count, i: i)
} }
// n-1 // n-1
for i in stride(from: nums.count - 1, to: 0, by: -1) { for i in nums.indices.dropFirst().reversed() {
// //
nums.swapAt(0, i) nums.swapAt(0, i)
// //

View File

@ -7,7 +7,7 @@
/* */ /* */
func insertionSort(nums: inout [Int]) { func insertionSort(nums: inout [Int]) {
// [0, i-1] // [0, i-1]
for i in stride(from: 1, to: nums.count, by: 1) { for i in nums.indices.dropFirst() {
let base = nums[i] let base = nums[i]
var j = i - 1 var j = i - 1
// base [0, i-1] // base [0, i-1]

View File

@ -16,12 +16,11 @@ func merge(nums: inout [Int], left: Int, mid: Int, right: Int) {
if nums[i] <= nums[j] { if nums[i] <= nums[j] {
tmp[k] = nums[i] tmp[k] = nums[i]
i += 1 i += 1
k += 1
} else { } else {
tmp[k] = nums[j] tmp[k] = nums[j]
j += 1 j += 1
k += 1
} }
k += 1
} }
// //
while i <= mid { while i <= mid {
@ -60,7 +59,7 @@ enum MergeSort {
static func main() { static func main() {
/* */ /* */
var nums = [7, 3, 2, 6, 0, 1, 5, 4] var nums = [7, 3, 2, 6, 0, 1, 5, 4]
mergeSort(nums: &nums, left: 0, right: nums.count - 1) mergeSort(nums: &nums, left: nums.startIndex, right: nums.endIndex - 1)
print("归并排序完成后 nums = \(nums)") print("归并排序完成后 nums = \(nums)")
} }
} }

View File

@ -4,13 +4,6 @@
* Author: nuomi1 (nuomi1@qq.com) * Author: nuomi1 (nuomi1@qq.com)
*/ */
/* */
func swap(nums: inout [Int], i: Int, j: Int) {
let tmp = nums[i]
nums[i] = nums[j]
nums[j] = tmp
}
/* */ /* */
/* */ /* */
func partition(nums: inout [Int], left: Int, right: Int) -> Int { func partition(nums: inout [Int], left: Int, right: Int) -> Int {
@ -24,9 +17,9 @@ func partition(nums: inout [Int], left: Int, right: Int) -> Int {
while i < j, nums[i] <= nums[left] { while i < j, nums[i] <= nums[left] {
i += 1 // i += 1 //
} }
swap(nums: &nums, i: i, j: j) // nums.swapAt(i, j) //
} }
swap(nums: &nums, i: i, j: left) // 线 nums.swapAt(i, left) // 线
return i // return i //
} }
@ -43,7 +36,6 @@ func quickSort(nums: inout [Int], left: Int, right: Int) {
quickSort(nums: &nums, left: pivot + 1, right: right) quickSort(nums: &nums, left: pivot + 1, right: right)
} }
/* */ /* */
/* */ /* */
func medianThree(nums: [Int], left: Int, mid: Int, right: Int) -> Int { func medianThree(nums: [Int], left: Int, mid: Int, right: Int) -> Int {
@ -51,12 +43,12 @@ func medianThree(nums: [Int], left: Int, mid: Int, right: Int) -> Int {
let m = nums[mid] let m = nums[mid]
let r = nums[right] let r = nums[right]
if (l <= m && m <= r) || (r <= m && m <= l) { if (l <= m && m <= r) || (r <= m && m <= l) {
return mid; // m l r return mid // m l r
} }
if (m <= l && l <= r) || (r <= l && l <= m) { if (m <= l && l <= r) || (r <= l && l <= m) {
return left; // l m r return left // l m r
} }
return right; return right
} }
/* */ /* */
@ -64,7 +56,7 @@ func partitionMedian(nums: inout [Int], left: Int, right: Int) -> Int {
// //
let med = medianThree(nums: nums, left: left, mid: (left + right) / 2, right: right) let med = medianThree(nums: nums, left: left, mid: (left + right) / 2, right: right)
// //
swap(nums: &nums, i: left, j: med) nums.swapAt(left, med)
return partition(nums: &nums, left: left, right: right) return partition(nums: &nums, left: left, right: right)
} }
@ -81,7 +73,6 @@ func quickSortMedian(nums: inout [Int], left: Int, right: Int) {
quickSortMedian(nums: &nums, left: pivot + 1, right: right) quickSortMedian(nums: &nums, left: pivot + 1, right: right)
} }
/* */ /* */
func quickSortTailCall(nums: inout [Int], left: Int, right: Int) { func quickSortTailCall(nums: inout [Int], left: Int, right: Int) {
var left = left var left = left
@ -107,17 +98,17 @@ enum QuickSort {
static func main() { static func main() {
/* */ /* */
var nums = [2, 4, 1, 0, 3, 5] var nums = [2, 4, 1, 0, 3, 5]
quickSort(nums: &nums, left: 0, right: nums.count - 1) quickSort(nums: &nums, left: nums.startIndex, right: nums.endIndex - 1)
print("快速排序完成后 nums = \(nums)") print("快速排序完成后 nums = \(nums)")
/* */ /* */
var nums1 = [2, 4, 1, 0, 3, 5] var nums1 = [2, 4, 1, 0, 3, 5]
quickSortMedian(nums: &nums1, left: 0, right: nums1.count - 1) quickSortMedian(nums: &nums1, left: nums1.startIndex, right: nums1.endIndex - 1)
print("快速排序(中位基准数优化)完成后 nums1 = \(nums1)") print("快速排序(中位基准数优化)完成后 nums1 = \(nums1)")
/* */ /* */
var nums2 = [2, 4, 1, 0, 3, 5] var nums2 = [2, 4, 1, 0, 3, 5]
quickSortTailCall(nums: &nums2, left: 0, right: nums2.count - 1) quickSortTailCall(nums: &nums2, left: nums2.startIndex, right: nums2.endIndex - 1)
print("快速排序(尾递归优化)完成后 nums2 = \(nums2)") print("快速排序(尾递归优化)完成后 nums2 = \(nums2)")
} }
} }

View File

@ -14,7 +14,6 @@ func digit(num: Int, exp: Int) -> Int {
func countingSortDigit(nums: inout [Int], exp: Int) { func countingSortDigit(nums: inout [Int], exp: Int) {
// 0~9 10 // 0~9 10
var counter = Array(repeating: 0, count: 10) var counter = Array(repeating: 0, count: 10)
let n = nums.count
// 0~9 // 0~9
for i in nums.indices { for i in nums.indices {
let d = digit(num: nums[i], exp: exp) // nums[i] k d let d = digit(num: nums[i], exp: exp) // nums[i] k d
@ -25,8 +24,8 @@ func countingSortDigit(nums: inout [Int], exp: Int) {
counter[i] += counter[i - 1] counter[i] += counter[i - 1]
} }
// res // res
var res = Array(repeating: 0, count: n) var res = Array(repeating: 0, count: nums.count)
for i in stride(from: n - 1, through: 0, by: -1) { for i in nums.indices.reversed() {
let d = digit(num: nums[i], exp: exp) let d = digit(num: nums[i], exp: exp)
let j = counter[d] - 1 // d j let j = counter[d] - 1 // d j
res[j] = nums[i] // j res[j] = nums[i] // j
@ -62,8 +61,18 @@ enum RadixSort {
/* Driver Code */ /* Driver Code */
static func main() { static func main() {
// //
var nums = [10546151, 35663510, 42865989, 34862445, 81883077, var nums = [
88906420, 72429244, 30524779, 82060337, 63832996] 10_546_151,
35_663_510,
42_865_989,
34_862_445,
81_883_077,
88_906_420,
72_429_244,
30_524_779,
82_060_337,
63_832_996,
]
radixSort(nums: &nums) radixSort(nums: &nums)
print("基数排序完成后 nums = \(nums)") print("基数排序完成后 nums = \(nums)")
} }

View File

@ -8,13 +8,13 @@
class ArrayDeque { class ArrayDeque {
private var nums: [Int] // private var nums: [Int] //
private var front: Int // private var front: Int //
private var queSize: Int // private var _size: Int //
/* */ /* */
init(capacity: Int) { init(capacity: Int) {
nums = Array(repeating: 0, count: capacity) nums = Array(repeating: 0, count: capacity)
front = 0 front = 0
queSize = 0 _size = 0
} }
/* */ /* */
@ -24,7 +24,7 @@ class ArrayDeque {
/* */ /* */
func size() -> Int { func size() -> Int {
queSize _size
} }
/* */ /* */
@ -51,7 +51,7 @@ class ArrayDeque {
front = index(i: front - 1) front = index(i: front - 1)
// num // num
nums[front] = num nums[front] = num
queSize += 1 _size += 1
} }
/* */ /* */
@ -64,7 +64,7 @@ class ArrayDeque {
let rear = index(i: front + size()) let rear = index(i: front + size())
// num // num
nums[rear] = num nums[rear] = num
queSize += 1 _size += 1
} }
/* */ /* */
@ -72,14 +72,14 @@ class ArrayDeque {
let num = peekFirst() let num = peekFirst()
// //
front = index(i: front + 1) front = index(i: front + 1)
queSize -= 1 _size -= 1
return num return num
} }
/* */ /* */
func popLast() -> Int { func popLast() -> Int {
let num = peekLast() let num = peekLast()
queSize -= 1 _size -= 1
return num return num
} }
@ -104,11 +104,7 @@ class ArrayDeque {
/* */ /* */
func toArray() -> [Int] { func toArray() -> [Int] {
// //
var res = Array(repeating: 0, count: size()) (front ..< front + size()).map { nums[index(i: $0)] }
for (i, j) in sequence(first: (0, front), next: { $0 < self.size() - 1 ? ($0 + 1, $1 + 1) : nil }) {
res[i] = nums[index(i: j)]
}
return res
} }
} }

View File

@ -7,12 +7,14 @@
/* */ /* */
class ArrayQueue { class ArrayQueue {
private var nums: [Int] // private var nums: [Int] //
private var front = 0 // private var front: Int //
private var queSize = 0 // private var _size: Int //
init(capacity: Int) { init(capacity: Int) {
// //
nums = Array(repeating: 0, count: capacity) nums = Array(repeating: 0, count: capacity)
front = 0
_size = 0
} }
/* */ /* */
@ -22,12 +24,12 @@ class ArrayQueue {
/* */ /* */
func size() -> Int { func size() -> Int {
queSize _size
} }
/* */ /* */
func isEmpty() -> Bool { func isEmpty() -> Bool {
queSize == 0 size() == 0
} }
/* */ /* */
@ -38,10 +40,10 @@ class ArrayQueue {
} }
// + 1 // + 1
// rear // rear
let rear = (front + queSize) % capacity() let rear = (front + size()) % capacity()
// num // num
nums[rear] = num nums[rear] = num
queSize += 1 _size += 1
} }
/* */ /* */
@ -50,7 +52,7 @@ class ArrayQueue {
let num = peek() let num = peek()
// //
front = (front + 1) % capacity() front = (front + 1) % capacity()
queSize -= 1 _size -= 1
return num return num
} }
@ -65,11 +67,7 @@ class ArrayQueue {
/* */ /* */
func toArray() -> [Int] { func toArray() -> [Int] {
// //
var res = Array(repeating: 0, count: queSize) (front ..< front + size()).map { nums[$0 % capacity()] }
for (i, j) in sequence(first: (0, front), next: { $0 < self.queSize - 1 ? ($0 + 1, $1 + 1) : nil }) {
res[i] = nums[j % capacity()]
}
return res
} }
} }

View File

@ -19,15 +19,15 @@ class ListNode {
class LinkedListDeque { class LinkedListDeque {
private var front: ListNode? // front private var front: ListNode? // front
private var rear: ListNode? // rear private var rear: ListNode? // rear
private var queSize: Int // private var _size: Int //
init() { init() {
queSize = 0 _size = 0
} }
/* */ /* */
func size() -> Int { func size() -> Int {
queSize _size
} }
/* */ /* */
@ -57,7 +57,7 @@ class LinkedListDeque {
node.prev = rear node.prev = rear
rear = node // rear = node //
} }
queSize += 1 // _size += 1 //
} }
/* */ /* */
@ -98,7 +98,7 @@ class LinkedListDeque {
} }
rear = rPrev // rear = rPrev //
} }
queSize -= 1 // _size -= 1 //
return val return val
} }
@ -113,13 +113,19 @@ class LinkedListDeque {
} }
/* 访 */ /* 访 */
func peekFirst() -> Int? { func peekFirst() -> Int {
isEmpty() ? nil : front?.val if isEmpty() {
fatalError("双向队列为空")
}
return front!.val
} }
/* 访 */ /* 访 */
func peekLast() -> Int? { func peekLast() -> Int {
isEmpty() ? nil : rear?.val if isEmpty() {
fatalError("双向队列为空")
}
return rear!.val
} }
/* */ /* */
@ -147,9 +153,9 @@ enum _LinkedListDeque {
/* 访 */ /* 访 */
let peekFirst = deque.peekFirst() let peekFirst = deque.peekFirst()
print("队首元素 peekFirst = \(peekFirst!)") print("队首元素 peekFirst = \(peekFirst)")
let peekLast = deque.peekLast() let peekLast = deque.peekLast()
print("队尾元素 peekLast = \(peekLast!)") print("队尾元素 peekLast = \(peekLast)")
/* */ /* */
deque.pushLast(num: 4) deque.pushLast(num: 4)

View File

@ -10,9 +10,11 @@ import utils
class LinkedListQueue { class LinkedListQueue {
private var front: ListNode? // private var front: ListNode? //
private var rear: ListNode? // private var rear: ListNode? //
private var _size = 0 private var _size: Int
init() {} init() {
_size = 0
}
/* */ /* */
func size() -> Int { func size() -> Int {

View File

@ -9,9 +9,11 @@ import utils
/* */ /* */
class LinkedListStack { class LinkedListStack {
private var _peek: ListNode? // private var _peek: ListNode? //
private var _size = 0 // private var _size: Int //
init() {} init() {
_size = 0
}
/* */ /* */
func size() -> Int { func size() -> Int {
@ -51,8 +53,8 @@ class LinkedListStack {
/* List Array */ /* List Array */
func toArray() -> [Int] { func toArray() -> [Int] {
var node = _peek var node = _peek
var res = Array(repeating: 0, count: _size) var res = Array(repeating: 0, count: size())
for i in sequence(first: res.count - 1, next: { $0 >= 0 + 1 ? $0 - 1 : nil }) { for i in res.indices.reversed() {
res[i] = node!.val res[i] = node!.val
node = node?.next node = node?.next
} }

View File

@ -48,7 +48,7 @@ class ArrayBinaryTree {
func levelOrder() -> [Int] { func levelOrder() -> [Int] {
var res: [Int] = [] var res: [Int] = []
// //
for i in stride(from: 0, to: size(), by: 1) { for i in 0 ..< size() {
if let val = val(i: i) { if let val = val(i: i) {
res.append(val) res.append(val)
} }

View File

@ -10,10 +10,12 @@ import utils
class AVLTree { class AVLTree {
fileprivate var root: TreeNode? // fileprivate var root: TreeNode? //
init() {}
/* */ /* */
func height(node: TreeNode?) -> Int { func height(node: TreeNode?) -> Int {
// -1 0 // -1 0
node == nil ? -1 : node!.height node?.height ?? -1
} }
/* */ /* */
@ -132,7 +134,7 @@ class AVLTree {
node?.right = removeHelper(node: node?.right, val: val) node?.right = removeHelper(node: node?.right, val: val)
} else { } else {
if node?.left == nil || node?.right == nil { if node?.left == nil || node?.right == nil {
let child = node?.left != nil ? node?.left : node?.right let child = node?.left ?? node?.right
// = 0 node // = 0 node
if child == nil { if child == nil {
return nil return nil

View File

@ -108,7 +108,7 @@ class BinarySearchTree {
// = 0 or 1 // = 0 or 1
if cur?.left == nil || cur?.right == nil { if cur?.left == nil || cur?.right == nil {
// = 0 / 1 child = null / // = 0 / 1 child = null /
let child = cur?.left != nil ? cur?.left : cur?.right let child = cur?.left ?? cur?.right
// cur // cur
if cur !== root { if cur !== root {
if pre?.left === cur { if pre?.left === cur {

View File

@ -22,19 +22,11 @@ public class Vertex: Hashable {
/* vals vets */ /* vals vets */
public static func valsToVets(vals: [Int]) -> [Vertex] { public static func valsToVets(vals: [Int]) -> [Vertex] {
var vets: [Vertex] = [] vals.map { Vertex(val: $0) }
for val in vals {
vets.append(Vertex(val: val))
}
return vets
} }
/* vets vals */ /* vets vals */
public static func vetsToVals(vets: [Vertex]) -> [Int] { public static func vetsToVals(vets: [Vertex]) -> [Int] {
var vals: [Int] = [] vets.map { $0.val }
for vet in vets {
vals.append(vet.val)
}
return vals
} }
} }

View File

@ -317,7 +317,7 @@ Let's understand this concept of "time growth trend" with an example. Assume the
// Time complexity of algorithm C: constant order // Time complexity of algorithm C: constant order
func algorithmC(n: Int) { func algorithmC(n: Int) {
for _ in 0 ..< 1000000 { for _ in 0 ..< 1_000_000 {
print(0) print(0)
} }
} }

View File

@ -101,10 +101,10 @@ In other words, **basic data types provide the "content type" of data, while dat
```swift title="" ```swift title=""
// Using various basic data types to initialize arrays // Using various basic data types to initialize arrays
let numbers = Array(repeating: Int(), count: 5) let numbers = Array(repeating: 0, count: 5)
let decimals = Array(repeating: Double(), count: 5) let decimals = Array(repeating: 0.0, count: 5)
let characters = Array(repeating: Character("a"), count: 5) let characters: [Character] = Array(repeating: "a", count: 5)
let bools = Array(repeating: Bool(), count: 5) let bools = Array(repeating: false, count: 5)
``` ```
=== "JS" === "JS"

View File

@ -317,7 +317,7 @@ $$
// 算法 C 的时间复杂度:常数阶 // 算法 C 的时间复杂度:常数阶
func algorithmC(n: Int) { func algorithmC(n: Int) {
for _ in 0 ..< 1000000 { for _ in 0 ..< 1_000_000 {
print(0) print(0)
} }
} }

View File

@ -101,10 +101,10 @@
```swift title="" ```swift title=""
// 使用多种基本数据类型来初始化数组 // 使用多种基本数据类型来初始化数组
let numbers = Array(repeating: Int(), count: 5) let numbers = Array(repeating: 0, count: 5)
let decimals = Array(repeating: Double(), count: 5) let decimals = Array(repeating: 0.0, count: 5)
let characters = Array(repeating: Character("a"), count: 5) let characters: [Character] = Array(repeating: "a", count: 5)
let bools = Array(repeating: Bool(), count: 5) let bools = Array(repeating: false, count: 5)
``` ```
=== "JS" === "JS"

View File

@ -270,7 +270,35 @@
=== "Swift" === "Swift"
```swift title="heap.swift" ```swift title="heap.swift"
// Swift 未提供内置 Heap 类 /* 初始化堆 */
// Swift 的 Heap 类型同时支持最大堆和最小堆,且需要引入 swift-collections
var heap = Heap<Int>()
/* 元素入堆 */
heap.insert(1)
heap.insert(3)
heap.insert(2)
heap.insert(5)
heap.insert(4)
/* 获取堆顶元素 */
var peek = heap.max()!
/* 堆顶元素出堆 */
peek = heap.removeMax() // 5
peek = heap.removeMax() // 4
peek = heap.removeMax() // 3
peek = heap.removeMax() // 2
peek = heap.removeMax() // 1
/* 获取堆大小 */
let size = heap.count
/* 判断堆是否为空 */
let isEmpty = heap.isEmpty
/* 输入列表并建堆 */
let heap2 = Heap([1, 3, 2, 5, 4])
``` ```
=== "JS" === "JS"