Skip to content

Commit 30d1684

Browse files
authored
Updated implementation of 4Sum
1 parent c760724 commit 30d1684

File tree

1 file changed

+54
-57
lines changed

1 file changed

+54
-57
lines changed
Lines changed: 54 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,58 @@
1-
func FourSum(_ nums: [Int], target: Int) -> [[Int]] {
2-
let a = nums.sorted()
3-
var ret: [[Int]] = []
4-
5-
for i in 0..<nums.count {
6-
if i != 0 && a[i] == a[i-1] {
7-
continue
8-
}
9-
for j in i+1..<nums.count {
10-
if j != i+1 && a[j] == a[j-1] {
11-
continue
12-
}
13-
14-
var k = j + 1
15-
var t = nums.count - 1
16-
17-
while k < t {
18-
let sum = a[i] + a[j] + a[k] + a[t]
19-
20-
if sum == target {
21-
ret.append([a[i], a[j], a[k], a[t]])
22-
k += 1
23-
} else if sum < target {
24-
k += 1
25-
} else {
26-
t -= 1
27-
}
28-
29-
if sum == target {
30-
while k < t {
31-
var flag = true
32-
if k != j + 1 && a[k] == a[k-1] {
33-
k += 1
34-
flag = false
35-
}
36-
37-
if t != nums.count - 1 && a[t] == a[t+1] {
38-
t -= 1
39-
flag = false
40-
}
41-
42-
if flag {
43-
break
44-
}
45-
}
46-
}
47-
}
1+
extension Collection where Element: Equatable {
2+
3+
/// In a sorted collection, replaces the given index with a successor mapping to a unique element.
4+
///
5+
/// - Parameter index: A valid index of the collection. `index` must be less than `endIndex`
6+
func formUniqueIndex(after index: inout Index) {
7+
var prev = index
8+
repeat {
9+
prev = index
10+
formIndex(after: &index)
11+
} while index < endIndex && self[prev] == self[index]
12+
}
13+
}
14+
15+
extension BidirectionalCollection where Element: Equatable {
16+
17+
/// In a sorted collection, replaces the given index with a predecessor that maps to a unique element.
18+
///
19+
/// - Parameter index: A valid index of the collection. `index` must be greater than `startIndex`.
20+
func formUniqueIndex(before index: inout Index) {
21+
var prev = index
22+
repeat {
23+
prev = index
24+
formIndex(before: &index)
25+
} while index > startIndex && self[prev] == self[index]
26+
}
27+
}
28+
29+
func fourSum<T: BidirectionalCollection>(_ collection: T, target: T.Element) -> [[T.Element]] where T.Element: Numeric & Comparable {
30+
let sorted = collection.sorted()
31+
var ret: [[T.Element]] = []
32+
33+
var l = sorted.startIndex
34+
while l < sorted.endIndex { defer { sorted.formUniqueIndex(after: &l) }
35+
var ml = sorted.index(after: l)
36+
while ml < sorted.endIndex { defer { sorted.formUniqueIndex(after: &ml) }
37+
var mr = sorted.index(after: ml)
38+
var r = sorted.index(before: sorted.endIndex)
39+
40+
while mr < r && r < sorted.endIndex {
41+
let sum = sorted[l] + sorted[ml] + sorted[mr] + sorted[r]
42+
if sum == target {
43+
ret.append([sorted[l], sorted[ml], sorted[mr], sorted[r]])
44+
sorted.formUniqueIndex(after: &mr)
45+
sorted.formUniqueIndex(before: &r)
46+
} else if sum < target {
47+
sorted.formUniqueIndex(after: &mr)
48+
} else {
49+
sorted.formUniqueIndex(before: &r)
4850
}
51+
}
4952
}
50-
51-
return ret
53+
}
54+
return ret
5255
}
5356

54-
/* Answer
55-
[
56-
[-1, 0, 0, 1],
57-
[-2, -1, 1, 2],
58-
[-2, 0, 0, 2]
59-
]
60-
*/
61-
FourSum([1, 0, -1, 0, -2, 2], target: 0)
57+
// answer: [[-2, -1, 1, 2], [-2, 0, 0, 2], [-1, 0, 0, 1]]
58+
fourSum([1, 0, -1, 0, -2, 2], target: 0)

0 commit comments

Comments
 (0)