3
3
print ( " Hello, Swift 4.2! " )
4
4
#endif
5
5
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
+
19
7
20
8
extension BidirectionalCollection where Element: Equatable {
21
9
@@ -32,33 +20,49 @@ extension BidirectionalCollection where Element: Equatable {
32
20
}
33
21
34
22
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 ] ] = [ ]
37
25
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)
41
34
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)
45
43
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
+ }
56
61
}
57
- }
58
62
}
59
- }
60
- return ret
63
+ return ret
61
64
}
62
65
66
+
63
67
// answer: [[-2, -1, 1, 2], [-2, 0, 0, 2], [-1, 0, 0, 1]]
64
68
fourSum ( [ 1 , 0 , - 1 , 0 , - 2 , 2 ] , target: 0 )
0 commit comments