|
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) |
48 | 50 | }
|
| 51 | + } |
49 | 52 | }
|
50 |
| - |
51 |
| - return ret |
| 53 | + } |
| 54 | + return ret |
52 | 55 | }
|
53 | 56 |
|
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