LeetCode 数组 101 Swift 练习

上一次刷算法已经是两年前了,今年四月份的时候把之前刷的重新过一遍,但毕竟只是 easy 题集,还得按着各个数据结构逐一复习,今天先开始 LeetCode 数组 101


Introduction

Max Consecutive Ones

485-c1.swiftview raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
//
// 485-c1.swift
// LeetCode
//
// Created by nuomi1 on 2021/5/1.
//

// Max Consecutive Ones
// https://leetcode.com/explore/learn/card/fun-with-arrays/521/introduction/3238/
// https://leetcode.com/problems/max-consecutive-ones/

// 最大连续 1 的个数
// https://leetcode-cn.com/problems/max-consecutive-ones/

// MARK: 一次遍历

func findMaxConsecutiveOnes(_ nums: [Int]) -> Int {
var maxCount = 0
var currentCount = 0

for number in nums {
if number == 1 {
currentCount += 1
} else {
maxCount = max(currentCount, maxCount)
currentCount = 0
}
}

maxCount = max(currentCount, maxCount)

return maxCount
}

Find Numbers with Even Number of Digits

1295-c2.swiftview raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
//
// 1295-c2.swift
// LeetCode
//
// Created by nuomi1 on 2021/5/2.
//

// Find Numbers with Even Number of Digits
// https://leetcode.com/explore/learn/card/fun-with-arrays/521/introduction/3237/
// https://leetcode.com/problems/find-numbers-with-even-number-of-digits/

// 统计位数为偶数的数字
// https://leetcode-cn.com/problems/find-numbers-with-even-number-of-digits/

// MARK: 枚举 + 数学

func findNumbers(_ nums: [Int]) -> Int {
var result = 0

for var number in nums {
var count = 0

while number != 0 {
count += 1
number /= 10
}

if count.isMultiple(of: 2) {
result += 1
}
}

return result
}

Squares of a Sorted Array

977-c3.swiftview raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
//
// 977-c3.swift
// LeetCode
//
// Created by nuomi1 on 2021/5/3.
// Updated by nuomi1 on 2021/5/18.
//

// Squares of a Sorted Array
// https://leetcode.com/explore/learn/card/fun-with-arrays/521/introduction/3240/
// https://leetcode.com/explore/learn/card/fun-with-arrays/523/conclusion/3574/
// https://leetcode.com/problems/squares-of-a-sorted-array/

// 有序数组的平方
// https://leetcode-cn.com/problems/squares-of-a-sorted-array/

// MARK: 双指针

func sortedSquares(_ nums: [Int]) -> [Int] {
var leftIndex = nums.startIndex
var rightIndex = nums.index(before: nums.endIndex)

var result = Array(repeating: 0, count: nums.count)
var currentIndex = result.index(before: result.endIndex)

while leftIndex <= rightIndex {
let lhs = nums[leftIndex] * nums[leftIndex]
let rhs = nums[rightIndex] * nums[rightIndex]

if lhs > rhs {
result[currentIndex] = lhs
nums.formIndex(after: &leftIndex)
} else {
result[currentIndex] = rhs
nums.formIndex(before: &rightIndex)
}

result.formIndex(before: &currentIndex)
}

return result
}

Inserting Items Into an Array

Duplicate Zeros

1089-e1.swiftview raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
//
// 1089-e1.swift
// LeetCode
//
// Created by nuomi1 on 2021/5/4.
//

// Duplicate Zeros
// https://leetcode.com/explore/learn/card/fun-with-arrays/525/inserting-items-into-an-array/3245/
// https://leetcode.com/problems/duplicate-zeros/

// 复写零
// https://leetcode-cn.com/problems/duplicate-zeros/

// MARK: Two pass, O(1) space

func duplicateZeros(_ arr: inout [Int]) {
var fastIndex = arr.index(before: arr.startIndex)
var slowIndex = arr.index(before: arr.startIndex)
var duplicateLast = false

while arr.index(after: fastIndex) < arr.endIndex {
arr.formIndex(after: &fastIndex)
arr.formIndex(after: &slowIndex)

if arr[slowIndex] == 0 {
if arr.index(after: fastIndex) == arr.endIndex {
duplicateLast = true
} else {
arr.formIndex(after: &fastIndex)
}
}
}

while arr.index(before: fastIndex) >= arr.startIndex {
arr[fastIndex] = arr[slowIndex]

if arr[slowIndex] == 0 {
if duplicateLast {
duplicateLast = false
} else {
arr.formIndex(before: &fastIndex)
arr[fastIndex] = 0
}
}

arr.formIndex(before: &fastIndex)
arr.formIndex(before: &slowIndex)
}
}

Merge Sorted Array

88-c3.swiftview raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
//
// 88-c3.swift
// LeetCode
//
// Created by nuomi1 on 2019/1/17.
// Updated by nuomi1 on 2021/5/5.
//

// Merge Sorted Array
// https://leetcode.com/explore/interview/card/top-interview-questions-easy/96/sorting-and-searching/587/
// https://leetcode.com/explore/learn/card/fun-with-arrays/525/inserting-items-into-an-array/3253/
// https://leetcode.com/problems/merge-sorted-array/

// 合并两个有序数组
// https://leetcode-cn.com/leetbook/read/top-interview-questions-easy/xnumcr/
// https://leetcode-cn.com/problems/merge-sorted-array/

// MARK: 逆向双指针

func merge(_ nums1: inout [Int], _ m: Int, _ nums2: [Int], _ n: Int) {
// nums1 扫描下标
var indexI = m - 1
// nums2 扫描下标
var indexJ = n - 1
// nums1 赋值下标
var indexTail = m + n - 1

while indexI >= nums1.startIndex || indexJ >= nums2.startIndex {
if indexI < nums1.startIndex {
nums1[indexTail] = nums2[indexJ]
nums2.formIndex(before: &indexJ)
} else if indexJ < nums2.startIndex {
nums1[indexTail] = nums1[indexI]
nums1.formIndex(before: &indexI)
} else if nums1[indexI] > nums2[indexJ] {
nums1[indexTail] = nums1[indexI]
nums1.formIndex(before: &indexI)
} else {
nums1[indexTail] = nums2[indexJ]
nums2.formIndex(before: &indexJ)
}
nums1.formIndex(before: &indexTail)
}
}

Deleting Items From an Array

Remove Element

27-e2.swiftview raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
//
// 27-e2.swift
// LeetCode
//
// Created by nuomi1 on 2021/5/6.
// Updated by nuomi1 on 2021/5/14.
//

// Remove Element
// https://leetcode.com/explore/learn/card/fun-with-arrays/526/deleting-items-from-an-array/3247/
// https://leetcode.com/explore/learn/card/fun-with-arrays/511/in-place-operations/3575/
// https://leetcode.com/problems/remove-element/

// 移除元素
// https://leetcode-cn.com/problems/remove-element/

// MARK: Two Pointers - when elements to remove are rare

func removeElement(_ nums: inout [Int], _ val: Int) -> Int {
var leftIndex = nums.startIndex
var rightIndex = nums.index(before: nums.endIndex)

while leftIndex < nums.index(after: rightIndex) {
if nums[leftIndex] == val {
nums[leftIndex] = nums[rightIndex]
nums.formIndex(before: &rightIndex)
} else {
nums.formIndex(after: &leftIndex)
}
}

let distance = nums.distance(from: nums.startIndex, to: rightIndex)
return distance + 1
}

Remove Duplicates from Sorted Array

26-e1.swiftview raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
//
// 26-e1.swift
// LeetCode
//
// Created by nuomi1 on 2018/12/17.
// Updated by nuomi1 on 2021/5/7.
// Updated by nuomi1 on 2021/5/11.
//

// Remove Duplicates from Sorted Array
// https://leetcode.com/explore/interview/card/top-interview-questions-easy/92/array/727/
// https://leetcode.com/explore/learn/card/fun-with-arrays/526/deleting-items-from-an-array/3248/
// https://leetcode.com/explore/learn/card/fun-with-arrays/511/in-place-operations/3258/
// https://leetcode.com/problems/remove-duplicates-from-sorted-array/

// 删除排序数组中的重复项
// https://leetcode-cn.com/leetbook/read/top-interview-questions-easy/x2gy9m/
// https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array/

// MARK: Two Pointers

func removeDuplicates(_ nums: inout [Int]) -> Int {
// 数组元素个数小于 2 时不需要处理
guard nums.count > 1 else {
return nums.count
}

// 对比下标
var leftIndex = nums.startIndex

// 扫描下标,跳过初始的对比下标
for rightIndex in nums.indices.dropFirst() {
// 对比下标与扫描下标的元素不相等,对比下标前进
if nums[leftIndex] != nums[rightIndex] {
nums.formIndex(after: &leftIndex)
nums[leftIndex] = nums[rightIndex]
}
}

// 返回个数为扫描下标加一
let distance = nums.distance(from: nums.startIndex, to: leftIndex)
return distance + 1
}

Searching for Items in an Array

Check If N and Its Double Exist

1346-c3.swiftview raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
//
// 1346-c3.swift
// LeetCode
//
// Created by nuomi1 on 2021/5/8.
//

// Check If N and Its Double Exist
// https://leetcode.com/explore/learn/card/fun-with-arrays/527/searching-for-items-in-an-array/3250/
// https://leetcode.com/problems/check-if-n-and-its-double-exist/

// 检查整数及其两倍数是否存在
// https://leetcode-cn.com/problems/check-if-n-and-its-double-exist/

// MARK: 哈希表

func checkIfExist(_ arr: [Int]) -> Bool {
let counts = arr.reduce(into: [Int: Int]()) {
$0[$1, default: 0] += 1
}

for number in arr {
if number != 0, counts[2 * number, default: 0] >= 1 {
return true
}

if number == 0, counts[2 * number, default: 0] >= 2 {
return true
}
}

return false
}

Valid Mountain Array

941-e1.swiftview raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
//
// 941-e1.swift
// LeetCode
//
// Created by nuomi1 on 2021/5/9.
//

// Valid Mountain Array
// https://leetcode.com/explore/learn/card/fun-with-arrays/527/searching-for-items-in-an-array/3251/
// https://leetcode.com/problems/valid-mountain-array/

// 有效的山脉数组
// https://leetcode-cn.com/problems/valid-mountain-array/

// MARK: One Pass

func validMountainArray(_ arr: [Int]) -> Bool {
var index = arr.startIndex

while arr.index(after: index) < arr.endIndex, arr[index] < arr[arr.index(after: index)] {
arr.formIndex(after: &index)
}

if index == arr.startIndex || index == arr.index(before: arr.endIndex) {
return false
}

while arr.index(after: index) < arr.endIndex, arr[index] > arr[arr.index(after: index)] {
arr.formIndex(after: &index)
}

return index == arr.index(before: arr.endIndex)
}

In-Place Operations

Replace Elements with Greatest Element on Right Side

1299-c1.swiftview raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
//
// 1299-c1.swift
// LeetCode
//
// Created by nuomi1 on 2021/5/10.
//

// Replace Elements with Greatest Element on Right Side
// https://leetcode.com/explore/learn/card/fun-with-arrays/511/in-place-operations/3259/
// https://leetcode.com/problems/replace-elements-with-greatest-element-on-right-side/

// 将每个元素替换为右侧最大元素
// https://leetcode-cn.com/problems/replace-elements-with-greatest-element-on-right-side/

// MARK: 逆序遍历

func replaceElements(_ arr: [Int]) -> [Int] {
var result = arr
var index = result.index(before: result.endIndex)

result[index] = -1
result.formIndex(before: &index)

while index >= result.startIndex {
let nextIndex = result.index(after: index)
result[index] = max(result[nextIndex], arr[nextIndex])
result.formIndex(before: &index)
}

return result
}

Remove Duplicates from Sorted Array

26-e1.swiftview raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
//
// 26-e1.swift
// LeetCode
//
// Created by nuomi1 on 2018/12/17.
// Updated by nuomi1 on 2021/5/7.
// Updated by nuomi1 on 2021/5/11.
//

// Remove Duplicates from Sorted Array
// https://leetcode.com/explore/interview/card/top-interview-questions-easy/92/array/727/
// https://leetcode.com/explore/learn/card/fun-with-arrays/526/deleting-items-from-an-array/3248/
// https://leetcode.com/explore/learn/card/fun-with-arrays/511/in-place-operations/3258/
// https://leetcode.com/problems/remove-duplicates-from-sorted-array/

// 删除排序数组中的重复项
// https://leetcode-cn.com/leetbook/read/top-interview-questions-easy/x2gy9m/
// https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array/

// MARK: Two Pointers

func removeDuplicates(_ nums: inout [Int]) -> Int {
// 数组元素个数小于 2 时不需要处理
guard nums.count > 1 else {
return nums.count
}

// 对比下标
var leftIndex = nums.startIndex

// 扫描下标,跳过初始的对比下标
for rightIndex in nums.indices.dropFirst() {
// 对比下标与扫描下标的元素不相等,对比下标前进
if nums[leftIndex] != nums[rightIndex] {
nums.formIndex(after: &leftIndex)
nums[leftIndex] = nums[rightIndex]
}
}

// 返回个数为扫描下标加一
let distance = nums.distance(from: nums.startIndex, to: leftIndex)
return distance + 1
}

Move Zeroes

283-e1.swiftview raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//
// 283-e1.swift
// LeetCode
//
// Created by nuomi1 on 2018/12/24.
// Updated by nuomi1 on 2021/5/12.
//

// Move Zeroes
// https://leetcode.com/explore/interview/card/top-interview-questions-easy/92/array/567/
// https://leetcode.com/explore/learn/card/fun-with-arrays/511/in-place-operations/3157/
// https://leetcode.com/problems/move-zeroes/

// 移动零
// https://leetcode-cn.com/leetbook/read/top-interview-questions-easy/x2ba4i/
// https://leetcode-cn.com/problems/move-zeroes/

// MARK: Space Sub-Optimal

func moveZeroes(_ nums: inout [Int]) {
// 统计 0 的个数
let count = nums.filter { $0 == 0 }.count
// 删除所有 0
nums.removeAll { $0 == 0 }
// 末尾补 0
nums.append(contentsOf: Array(repeating: 0, count: count))
}
283-e3.swiftview raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//
// 283-e3.swift
// LeetCode
//
// Created by nuomi1 on 2018/12/24.
// Updated by nuomi1 on 2021/5/12.
//

// Move Zeroes
// https://leetcode.com/explore/interview/card/top-interview-questions-easy/92/array/567/
// https://leetcode.com/explore/learn/card/fun-with-arrays/511/in-place-operations/3157/
// https://leetcode.com/problems/move-zeroes/

// 移动零
// https://leetcode-cn.com/leetbook/read/top-interview-questions-easy/x2ba4i/
// https://leetcode-cn.com/problems/move-zeroes/

// MARK: Optimal

func moveZeroes(_ nums: inout [Int]) {
var leftIndex = nums.startIndex

// 把非零项移动到前方,后方即为零项
for rightIndex in nums.indices {
if nums[rightIndex] != 0 {
nums.swapAt(rightIndex, leftIndex)
nums.formIndex(after: &leftIndex)
}
}
}

Sort Array By Parity

905-s1.swiftview raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
//
// 905-s1.swift
// LeetCode
//
// Created by nuomi1 on 2021/5/13.
//

// Sort Array By Parity
// https://leetcode.com/explore/learn/card/fun-with-arrays/511/in-place-operations/3260/
// https://leetcode.com/problems/sort-array-by-parity/

// 按奇偶排序数组
// https://leetcode-cn.com/problems/sort-array-by-parity/

func sortArrayByParity(_ nums: [Int]) -> [Int] {
var result = nums

var leftIndex = nums.startIndex
var rightIndex = nums.index(before: nums.endIndex)

for number in nums {
if number.isMultiple(of: 2) {
result[leftIndex] = number
result.formIndex(after: &leftIndex)
} else {
result[rightIndex] = number
result.formIndex(before: &rightIndex)
}
}

return result
}

Remove Element

27-e2.swiftview raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
//
// 27-e2.swift
// LeetCode
//
// Created by nuomi1 on 2021/5/6.
// Updated by nuomi1 on 2021/5/14.
//

// Remove Element
// https://leetcode.com/explore/learn/card/fun-with-arrays/526/deleting-items-from-an-array/3247/
// https://leetcode.com/explore/learn/card/fun-with-arrays/511/in-place-operations/3575/
// https://leetcode.com/problems/remove-element/

// 移除元素
// https://leetcode-cn.com/problems/remove-element/

// MARK: Two Pointers - when elements to remove are rare

func removeElement(_ nums: inout [Int], _ val: Int) -> Int {
var leftIndex = nums.startIndex
var rightIndex = nums.index(before: nums.endIndex)

while leftIndex < nums.index(after: rightIndex) {
if nums[leftIndex] == val {
nums[leftIndex] = nums[rightIndex]
nums.formIndex(before: &rightIndex)
} else {
nums.formIndex(after: &leftIndex)
}
}

let distance = nums.distance(from: nums.startIndex, to: rightIndex)
return distance + 1
}

Conclusion

Height Checker

1051-s1.swiftview raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
//
// 1051-s1.swift
// LeetCode
//
// Created by nuomi1 on 2021/5/15.
//

// Height Checker
// https://leetcode.com/explore/learn/card/fun-with-arrays/523/conclusion/3228/
// https://leetcode.com/problems/height-checker/

// 高度检查器
// https://leetcode-cn.com/problems/height-checker/

func heightChecker(_ heights: [Int]) -> Int {
var buckets = Array(repeating: 0, count: 101)

for height in heights {
buckets[height] += 1
}

var result = 0
var heightIndex = heights.startIndex

for bucketIndex in buckets.indices.dropFirst() {
while buckets[bucketIndex] > 0 {
if heights[heightIndex] != bucketIndex {
result += 1
}

heights.formIndex(after: &heightIndex)
buckets[bucketIndex] -= 1
}
}

return result
}

Third Maximum Number

414-s1.swiftview raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
//
// 414-s1.swift
// LeetCode
//
// Created by nuomi1 on 2021/5/16.
//

// Third Maximum Number
// https://leetcode.com/explore/learn/card/fun-with-arrays/523/conclusion/3231/
// https://leetcode.com/problems/third-maximum-number/

// 第三大的数
// https://leetcode-cn.com/problems/third-maximum-number/

func thirdMax(_ nums: [Int]) -> Int {
var counts: [Int] = []

for number in nums {
if counts.firstIndex(of: number) != nil {
continue
}

if let index = counts.firstIndex(where: { $0 > number }) {
counts.insert(number, at: index)
} else {
counts.append(number)
}

if counts.count > 3 {
counts.removeFirst()
}
}

return counts.count < 3 ? counts.last! : counts.first!
}

Find All Numbers Disappeared in an Array

448-c1.swiftview raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
//
// 448-c1.swift
// LeetCode
//
// Created by nuomi1 on 2021/5/17.
//

// Find All Numbers Disappeared in an Array
// https://leetcode.com/explore/learn/card/fun-with-arrays/523/conclusion/3270/
// https://leetcode.com/problems/find-all-numbers-disappeared-in-an-array/

// 找到所有数组中消失的数字
// https://leetcode-cn.com/problems/find-all-numbers-disappeared-in-an-array/

// MARK: 原地修改

func findDisappearedNumbers(_ nums: [Int]) -> [Int] {
var numbers = nums

for number in numbers {
let index = number - 1
numbers[index] += nums.count
}

var result: [Int] = []

for index in numbers.indices {
if numbers[index] <= nums.count {
result.append(index + 1)
}
}

return result
}

Squares of a Sorted Array

977-c3.swiftview raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
//
// 977-c3.swift
// LeetCode
//
// Created by nuomi1 on 2021/5/3.
// Updated by nuomi1 on 2021/5/18.
//

// Squares of a Sorted Array
// https://leetcode.com/explore/learn/card/fun-with-arrays/521/introduction/3240/
// https://leetcode.com/explore/learn/card/fun-with-arrays/523/conclusion/3574/
// https://leetcode.com/problems/squares-of-a-sorted-array/

// 有序数组的平方
// https://leetcode-cn.com/problems/squares-of-a-sorted-array/

// MARK: 双指针

func sortedSquares(_ nums: [Int]) -> [Int] {
var leftIndex = nums.startIndex
var rightIndex = nums.index(before: nums.endIndex)

var result = Array(repeating: 0, count: nums.count)
var currentIndex = result.index(before: result.endIndex)

while leftIndex <= rightIndex {
let lhs = nums[leftIndex] * nums[leftIndex]
let rhs = nums[rightIndex] * nums[rightIndex]

if lhs > rhs {
result[currentIndex] = lhs
nums.formIndex(after: &leftIndex)
} else {
result[currentIndex] = rhs
nums.formIndex(before: &rightIndex)
}

result.formIndex(before: &currentIndex)
}

return result
}