Skip to content

Commit f0720f5

Browse files
authored
Merge pull request #1 from CHIRAGGARORA/CHIRAGGARORA-patch-1
Improve fourSum function with unique quadruplets
2 parents e592ed6 + d776a22 commit f0720f5

File tree

1 file changed

+38
-34
lines changed

1 file changed

+38
-34
lines changed

3Sum and 4Sum/4Sum.playground/Contents.swift

Lines changed: 38 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,7 @@
33
print("Hello, Swift 4.2!")
44
#endif
55

6-
extension Collection where Element: Equatable {
7-
8-
/// In a sorted collection, replaces the given index with a successor mapping to a unique element.
9-
///
10-
/// - Parameter index: A valid index of the collection. `index` must be less than `endIndex`
11-
func formUniqueIndex(after index: inout Index) {
12-
var prev = index
13-
repeat {
14-
prev = index
15-
formIndex(after: &index)
16-
} while index < endIndex && self[prev] == self[index]
17-
}
18-
}
6+
197

208
extension BidirectionalCollection where Element: Equatable {
219

@@ -32,33 +20,49 @@ extension BidirectionalCollection where Element: Equatable {
3220
}
3321

3422
func fourSum<T: BidirectionalCollection>(_ collection: T, target: T.Element) -> [[T.Element]] where T.Element: Numeric & Comparable {
35-
let sorted = collection.sorted()
36-
var ret: [[T.Element]] = []
23+
let sorted = collection.sorted()
24+
var ret: [[T.Element]] = []
3725

38-
var l = sorted.startIndex
39-
FourSum: while l < sorted.endIndex { defer { sorted.formUniqueIndex(after: &l) }
40-
var ml = sorted.index(after: l)
26+
var l = sorted.startIndex
27+
FourSum: while l < sorted.endIndex {
28+
// Skip over any repeated elements
29+
while l < sorted.endIndex - 1, sorted[l] == sorted[sorted.index(after: l)] {
30+
sorted.formIndex(after: &l)
31+
}
32+
defer { sorted.formIndex(after: &l) }
33+
var ml = sorted.index(after: l)
4134

42-
ThreeSum: while ml < sorted.endIndex { defer { sorted.formUniqueIndex(after: &ml) }
43-
var mr = sorted.index(after: ml)
44-
var r = sorted.index(before: sorted.endIndex)
35+
ThreeSum: while ml < sorted.endIndex {
36+
// Skip over any repeated elements
37+
while ml < sorted.endIndex - 1, sorted[ml] == sorted[sorted.index(after: ml)] {
38+
sorted.formIndex(after: &ml)
39+
}
40+
defer { sorted.formIndex(after: &ml) }
41+
var mr = sorted.index(after: ml)
42+
var r = sorted.index(before: sorted.endIndex)
4543

46-
TwoSum: while mr < r && r < sorted.endIndex {
47-
let sum = sorted[l] + sorted[ml] + sorted[mr] + sorted[r]
48-
if sum == target {
49-
ret.append([sorted[l], sorted[ml], sorted[mr], sorted[r]])
50-
sorted.formUniqueIndex(after: &mr)
51-
sorted.formUniqueIndex(before: &r)
52-
} else if sum < target {
53-
sorted.formUniqueIndex(after: &mr)
54-
} else {
55-
sorted.formUniqueIndex(before: &r)
44+
TwoSum: while mr < r && r < sorted.endIndex {
45+
let sum = sorted[l] + sorted[ml] + sorted[mr] + sorted[r]
46+
if sum == target {
47+
ret.append([sorted[l], sorted[ml], sorted[mr], sorted[r]])
48+
// Skip over any repeated elements
49+
while mr < r, sorted[mr] == sorted[sorted.index(after: mr)] {
50+
sorted.formIndex(after: &mr)
51+
}
52+
while mr < r, sorted[r] == sorted[sorted.index(before: r)] {
53+
sorted.formIndex(before: &r)
54+
}
55+
} else if sum < target {
56+
sorted.formIndex(after: &mr)
57+
} else {
58+
sorted.formIndex(before: &r)
59+
}
60+
}
5661
}
57-
}
5862
}
59-
}
60-
return ret
63+
return ret
6164
}
6265

66+
6367
// answer: [[-2, -1, 1, 2], [-2, 0, 0, 2], [-1, 0, 0, 1]]
6468
fourSum([1, 0, -1, 0, -2, 2], target: 0)

0 commit comments

Comments
 (0)