Skip to content

Commit d776a22

Browse files
authored
Improve fourSum function with unique quadruplets
This commit improves the fourSum function by removing duplicates and returning only unique quadruplets that add up to the specific target. The code now also skips over any repeated elements in the input collection, making it more efficient and accurate. The unnecessary formUniqueIndex function is removed which is not needed in this version of the code, and minor changes are made to the existing code to improve readability and maintainability.
1 parent e592ed6 commit d776a22

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)