mirror of
https://github.com/krahets/hello-algo.git
synced 2024-12-26 01:56:31 +08:00
Merge branch 'master' of github.com:krahets/hello-algo
This commit is contained in:
commit
c411969bd1
4 changed files with 197 additions and 0 deletions
|
@ -9,6 +9,7 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <climits>
|
||||||
#include "ListNode.hpp"
|
#include "ListNode.hpp"
|
||||||
#include "TreeNode.hpp"
|
#include "TreeNode.hpp"
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ let package = Package(
|
||||||
.executable(name: "worst_best_time_complexity", targets: ["worst_best_time_complexity"]),
|
.executable(name: "worst_best_time_complexity", targets: ["worst_best_time_complexity"]),
|
||||||
.executable(name: "space_complexity", targets: ["space_complexity"]),
|
.executable(name: "space_complexity", targets: ["space_complexity"]),
|
||||||
.executable(name: "leetcode_two_sum", targets: ["leetcode_two_sum"]),
|
.executable(name: "leetcode_two_sum", targets: ["leetcode_two_sum"]),
|
||||||
|
.executable(name: "array", targets: ["array"]),
|
||||||
],
|
],
|
||||||
targets: [
|
targets: [
|
||||||
.target(name: "utils", path: "utils"),
|
.target(name: "utils", path: "utils"),
|
||||||
|
@ -16,5 +17,6 @@ let package = Package(
|
||||||
.executableTarget(name: "worst_best_time_complexity", path: "chapter_computational_complexity", sources: ["worst_best_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: "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"]),
|
.executableTarget(name: "leetcode_two_sum", path: "chapter_computational_complexity", sources: ["leetcode_two_sum.swift"]),
|
||||||
|
.executableTarget(name: "array", path: "chapter_array_and_linkedlist", sources: ["array.swift"]),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
103
codes/swift/chapter_array_and_linkedlist/array.swift
Normal file
103
codes/swift/chapter_array_and_linkedlist/array.swift
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
/**
|
||||||
|
* File: array.swift
|
||||||
|
* Created Time: 2023-01-05
|
||||||
|
* Author: nuomi1 (nuomi1@qq.com)
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 随机返回一个数组元素
|
||||||
|
func randomAccess(nums: [Int]) -> Int {
|
||||||
|
// 在区间 [0, nums.count) 中随机抽取一个数字
|
||||||
|
let randomIndex = nums.indices.randomElement()!
|
||||||
|
// 获取并返回随机元素
|
||||||
|
let randomNum = nums[randomIndex]
|
||||||
|
return randomNum
|
||||||
|
}
|
||||||
|
|
||||||
|
// 扩展数组长度
|
||||||
|
func extend(nums: [Int], enlarge: Int) -> [Int] {
|
||||||
|
// 初始化一个扩展长度后的数组
|
||||||
|
var res = Array(repeating: 0, count: nums.count + enlarge)
|
||||||
|
// 将原数组中的所有元素复制到新数组
|
||||||
|
for i in nums.indices {
|
||||||
|
res[i] = nums[i]
|
||||||
|
}
|
||||||
|
// 返回扩展后的新数组
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
// 在数组的索引 index 处插入元素 num
|
||||||
|
func insert(nums: inout [Int], num: Int, index: Int) {
|
||||||
|
// 把索引 index 以及之后的所有元素向后移动一位
|
||||||
|
for i in sequence(first: nums.count - 1, next: { $0 > index + 1 ? $0 - 1 : nil }) {
|
||||||
|
nums[i] = nums[i - 1]
|
||||||
|
}
|
||||||
|
// 将 num 赋给 index 处元素
|
||||||
|
nums[index] = num
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除索引 index 处元素
|
||||||
|
func remove(nums: inout [Int], index: Int) {
|
||||||
|
let count = nums.count
|
||||||
|
// 把索引 index 之后的所有元素向前移动一位
|
||||||
|
for i in sequence(first: index, next: { $0 < count - 1 - 1 ? $0 + 1 : nil }) {
|
||||||
|
nums[i] = nums[i + 1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 遍历数组
|
||||||
|
func traverse(nums: [Int]) {
|
||||||
|
var count = 0
|
||||||
|
// 通过索引遍历数组
|
||||||
|
for _ in nums.indices {
|
||||||
|
count += 1
|
||||||
|
}
|
||||||
|
// 直接遍历数组
|
||||||
|
for _ in nums {
|
||||||
|
count += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 在数组中查找指定元素
|
||||||
|
func find(nums: [Int], target: Int) -> Int {
|
||||||
|
for i in nums.indices {
|
||||||
|
if nums[i] == target {
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
@main
|
||||||
|
enum _Array {
|
||||||
|
// Driver Code
|
||||||
|
static func main() {
|
||||||
|
// 初始化数组
|
||||||
|
let arr = Array(repeating: 0, count: 5)
|
||||||
|
print("数组 arr = \(arr)")
|
||||||
|
var nums = [1, 3, 2, 5, 4]
|
||||||
|
print("数组 nums = \(nums)")
|
||||||
|
|
||||||
|
// 随机访问
|
||||||
|
let randomNum = randomAccess(nums: nums)
|
||||||
|
print("在 nums 中获取随机元素 \(randomNum)")
|
||||||
|
|
||||||
|
// 长度扩展
|
||||||
|
nums = extend(nums: nums, enlarge: 3)
|
||||||
|
print("将数组长度扩展至 8 ,得到 nums = \(nums)")
|
||||||
|
|
||||||
|
// 插入元素
|
||||||
|
insert(nums: &nums, num: 6, index: 3)
|
||||||
|
print("在索引 3 处插入数字 6 ,得到 nums = \(nums)")
|
||||||
|
|
||||||
|
// 删除元素
|
||||||
|
remove(nums: &nums, index: 2)
|
||||||
|
print("删除索引 2 处的元素,得到 nums = \(nums)")
|
||||||
|
|
||||||
|
// 遍历数组
|
||||||
|
traverse(nums: nums)
|
||||||
|
|
||||||
|
// 查找元素
|
||||||
|
let index = find(nums: nums, target: 3)
|
||||||
|
print("在 nums 中查找元素 3 ,得到索引 = \(index)")
|
||||||
|
}
|
||||||
|
}
|
|
@ -81,6 +81,14 @@ comments: true
|
||||||
int[] nums = { 1, 3, 2, 5, 4 };
|
int[] nums = { 1, 3, 2, 5, 4 };
|
||||||
```
|
```
|
||||||
|
|
||||||
|
=== "Swift"
|
||||||
|
|
||||||
|
```swift title="array.swift"
|
||||||
|
// 初始化数组
|
||||||
|
let arr = Array(repeating: 0, count: 5) // [0, 0, 0, 0, 0]
|
||||||
|
let nums = [1, 3, 2, 5, 4]
|
||||||
|
```
|
||||||
|
|
||||||
## 数组优点
|
## 数组优点
|
||||||
|
|
||||||
**在数组中访问元素非常高效**。这是因为在数组中,计算元素的内存地址非常容易。给定数组首个元素的地址、和一个元素的索引,利用以下公式可以直接计算得到该元素的内存地址,从而直接访问此元素。
|
**在数组中访问元素非常高效**。这是因为在数组中,计算元素的内存地址非常容易。给定数组首个元素的地址、和一个元素的索引,利用以下公式可以直接计算得到该元素的内存地址,从而直接访问此元素。
|
||||||
|
@ -193,6 +201,19 @@ elementAddr = firtstElementAddr + elementLength * elementIndex
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
=== "Swift"
|
||||||
|
|
||||||
|
```swift title="array.swift"
|
||||||
|
// 随机返回一个数组元素
|
||||||
|
func randomAccess(nums: [Int]) -> Int {
|
||||||
|
// 在区间 [0, nums.count) 中随机抽取一个数字
|
||||||
|
let randomIndex = nums.indices.randomElement()!
|
||||||
|
// 获取并返回随机元素
|
||||||
|
let randomNum = nums[randomIndex]
|
||||||
|
return randomNum
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## 数组缺点
|
## 数组缺点
|
||||||
|
|
||||||
**数组在初始化后长度不可变**。由于系统无法保证数组之后的内存空间是可用的,因此数组长度无法扩展。而若希望扩容数组,则需新建一个数组,然后把原数组元素依次拷贝到新数组,在数组很大的情况下,这是非常耗时的。
|
**数组在初始化后长度不可变**。由于系统无法保证数组之后的内存空间是可用的,因此数组长度无法扩展。而若希望扩容数组,则需新建一个数组,然后把原数组元素依次拷贝到新数组,在数组很大的情况下,这是非常耗时的。
|
||||||
|
@ -317,6 +338,22 @@ elementAddr = firtstElementAddr + elementLength * elementIndex
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
=== "Swift"
|
||||||
|
|
||||||
|
```swift title="array.swift"
|
||||||
|
// 扩展数组长度
|
||||||
|
func extend(nums: [Int], enlarge: Int) -> [Int] {
|
||||||
|
// 初始化一个扩展长度后的数组
|
||||||
|
var res = Array(repeating: 0, count: nums.count + enlarge)
|
||||||
|
// 将原数组中的所有元素复制到新数组
|
||||||
|
for i in nums.indices {
|
||||||
|
res[i] = nums[i]
|
||||||
|
}
|
||||||
|
// 返回扩展后的新数组
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
**数组中插入或删除元素效率低下**。假设我们想要在数组中间某位置插入一个元素,由于数组元素在内存中是“紧挨着的”,它们之间没有空间再放任何数据。因此,我们不得不将此索引之后的所有元素都向后移动一位,然后再把元素赋值给该索引。删除元素也是类似,需要把此索引之后的元素都向前移动一位。总体看有以下缺点:
|
**数组中插入或删除元素效率低下**。假设我们想要在数组中间某位置插入一个元素,由于数组元素在内存中是“紧挨着的”,它们之间没有空间再放任何数据。因此,我们不得不将此索引之后的所有元素都向后移动一位,然后再把元素赋值给该索引。删除元素也是类似,需要把此索引之后的元素都向前移动一位。总体看有以下缺点:
|
||||||
|
|
||||||
- **时间复杂度高:** 数组的插入和删除的平均时间复杂度均为 $O(N)$ ,其中 $N$ 为数组长度。
|
- **时间复杂度高:** 数组的插入和删除的平均时间复杂度均为 $O(N)$ ,其中 $N$ 为数组长度。
|
||||||
|
@ -486,6 +523,29 @@ elementAddr = firtstElementAddr + elementLength * elementIndex
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
=== "Swift"
|
||||||
|
|
||||||
|
```swift title="array.swift"
|
||||||
|
// 在数组的索引 index 处插入元素 num
|
||||||
|
func insert(nums: inout [Int], num: Int, index: Int) {
|
||||||
|
// 把索引 index 以及之后的所有元素向后移动一位
|
||||||
|
for i in sequence(first: nums.count - 1, next: { $0 > index + 1 ? $0 - 1 : nil }) {
|
||||||
|
nums[i] = nums[i - 1]
|
||||||
|
}
|
||||||
|
// 将 num 赋给 index 处元素
|
||||||
|
nums[index] = num
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除索引 index 处元素
|
||||||
|
func remove(nums: inout [Int], index: Int) {
|
||||||
|
let count = nums.count
|
||||||
|
// 把索引 index 之后的所有元素向前移动一位
|
||||||
|
for i in sequence(first: index, next: { $0 < count - 1 - 1 ? $0 + 1 : nil }) {
|
||||||
|
nums[i] = nums[i + 1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## 数组常用操作
|
## 数组常用操作
|
||||||
|
|
||||||
**数组遍历**。以下介绍两种常用的遍历方法。
|
**数组遍历**。以下介绍两种常用的遍历方法。
|
||||||
|
@ -611,6 +671,23 @@ elementAddr = firtstElementAddr + elementLength * elementIndex
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
=== "Swift"
|
||||||
|
|
||||||
|
```swift title="array.swift"
|
||||||
|
// 遍历数组
|
||||||
|
func traverse(nums: [Int]) {
|
||||||
|
var count = 0
|
||||||
|
// 通过索引遍历数组
|
||||||
|
for _ in nums.indices {
|
||||||
|
count += 1
|
||||||
|
}
|
||||||
|
// 直接遍历数组
|
||||||
|
for _ in nums {
|
||||||
|
count += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
**数组查找**。通过遍历数组,查找数组内的指定元素,并输出对应索引。
|
**数组查找**。通过遍历数组,查找数组内的指定元素,并输出对应索引。
|
||||||
|
|
||||||
=== "Java"
|
=== "Java"
|
||||||
|
@ -713,6 +790,20 @@ elementAddr = firtstElementAddr + elementLength * elementIndex
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
=== "Swift"
|
||||||
|
|
||||||
|
```swift title="array.swift"
|
||||||
|
// 在数组中查找指定元素
|
||||||
|
func find(nums: [Int], target: Int) -> Int {
|
||||||
|
for i in nums.indices {
|
||||||
|
if nums[i] == target {
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## 数组典型应用
|
## 数组典型应用
|
||||||
|
|
||||||
**随机访问**。如果我们想要随机抽取一些样本,那么可以用数组存储,并生成一个随机序列,根据索引实现样本的随机抽取。
|
**随机访问**。如果我们想要随机抽取一些样本,那么可以用数组存储,并生成一个随机序列,根据索引实现样本的随机抽取。
|
||||||
|
|
Loading…
Reference in a new issue