Skip to content

Commit 1c4ce41

Browse files
authored
Updated readme based on code changes.
1 parent e4d1fae commit 1c4ce41

File tree

1 file changed

+28
-37
lines changed

1 file changed

+28
-37
lines changed

3Sum and 4Sum/README.md

Lines changed: 28 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -29,19 +29,15 @@ Since you pre-sort the array, duplicates will be adjacent to each other. You jus
2929
```
3030
extension Collection where Element: Equatable {
3131
32-
/// Returns next index with unique value. Works only on sorted arrays.
32+
/// In a sorted collection, replaces the given index with a successor mapping to a unique element.
3333
///
34-
/// - Parameter index: The current index.
35-
/// - Returns: The new index. Will return `nil` if new index happens to be the `endIndex` (out of bounds)
36-
func uniqueIndex(after index: Index) -> Index? {
37-
guard index < endIndex else { return nil }
38-
var index = index
39-
var nextIndex = self.index(after: index)
40-
while nextIndex < endIndex && self[index] == self[nextIndex] {
34+
/// - Parameter index: A valid index of the collection. `index` must be less than `endIndex`
35+
func formUniqueIndex(after index: inout Index) {
36+
var prev = index
37+
repeat {
38+
prev = index
4139
formIndex(after: &index)
42-
formIndex(after: &nextIndex)
43-
}
44-
return nextIndex != endIndex ? nextIndex : nil
40+
} while index < endIndex && self[prev] == self[index]
4541
}
4642
}
4743
```
@@ -51,16 +47,15 @@ A similar implementation is used to get the unique index *before* a given index:
5147
```
5248
extension BidirectionalCollection where Element: Equatable {
5349
54-
/// Returns next index with unique value. Works only on sorted arrays.
50+
/// In a sorted collection, replaces the given index with a predecessor that maps to a unique element.
5551
///
56-
/// - Parameter index: The current index.
57-
/// - Returns: The new index. Will return `nil` if new index happens to come before the `startIndex` (out of bounds)
58-
func uniqueIndex(before index: Index) -> Index? {
59-
return indices[..<index].reversed().first { index -> Bool in
60-
let nextIndex = self.index(after: index)
61-
guard nextIndex >= startIndex && self[index] != self[nextIndex] else { return false }
62-
return true
63-
}
52+
/// - Parameter index: A valid index of the collection. `index` must be greater than `startIndex`.
53+
func formUniqueIndex(before index: inout Index) {
54+
var prev = index
55+
repeat {
56+
prev = index
57+
formIndex(before: &index)
58+
} while index > startIndex && self[prev] == self[index]
6459
}
6560
}
6661
```
@@ -78,40 +73,36 @@ You'll keep track of 3 indices to represent the 3 numbers. The sum at any given
7873
The premise is quite straightforward (given that you're familiar with 2Sum). You'll iterate `l` through the array. For every iteration, you also apply the 2Sum algorithm to elements after `l`. You'll check the sum every time you moving the indices to check if you found match. Here's the algorithm:
7974

8075
```
81-
func threeSum<T: BidirectionalCollection>(_ c: T, target: T.Element) -> [[T.Element]] where T.Element: Numeric & Comparable {
82-
let sorted = c.sorted()
76+
func threeSum<T: BidirectionalCollection>(_ collection: T, target: T.Element) -> [[T.Element]] where T.Element: Numeric & Comparable {
77+
let sorted = collection.sorted()
8378
var ret: [[T.Element]] = []
79+
var l = sorted.startIndex
8480
85-
for l in sequence(first: sorted.startIndex, next: sorted.uniqueIndex(after:)) {
81+
while l < sorted.endIndex {
8682
var m = sorted.index(after: l)
8783
var r = sorted.index(before: sorted.endIndex)
8884
89-
while m < r {
85+
while m < r && r < sorted.endIndex {
9086
let sum = sorted[l] + sorted[m] + sorted[r]
91-
switch sum {
92-
case target:
87+
switch target {
88+
case sum:
9389
ret.append([sorted[l], sorted[m], sorted[r]])
94-
guard let nextM = sorted.uniqueIndex(after: m), let nextR = sorted.uniqueIndex(before: r) else { break }
95-
m = nextM
96-
r = nextR
90+
sorted.formUniqueIndex(after: &m)
91+
sorted.formUniqueIndex(before: &r)
9792
case ..<target:
98-
guard let nextM = sorted.uniqueIndex(after: m) else { break }
99-
m = nextM
93+
sorted.formUniqueIndex(after: &m)
10094
case target...:
101-
guard let nextR = sorted.uniqueIndex(before: m) else { break }
102-
r = nextR
103-
default: fatalError()
95+
sorted.formUniqueIndex(before: &r)
96+
default: fatalError("Swift isn't smart enough to detect that this switch statement is exhausive")
10497
}
10598
}
99+
sorted.formUniqueIndex(after: &l)
106100
}
107101
108102
return ret
109103
}
110104
```
111105

112-
113-
114-
115106
## 4Sum
116107
Given an array S of n integers, find all subsets of the array with 4 values where the 4 values sum up to a target number.
117108

0 commit comments

Comments
 (0)