You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: 3Sum and 4Sum/README.md
+44-38Lines changed: 44 additions & 38 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -111,45 +111,51 @@ There are slight optimizations you can do to find `m`, but to keep things simple
111
111
112
112
#### Avoiding Duplicates
113
113
114
-
Avoiding duplicate values is fairly straightforward if you've understood everything so far. Let's consider a sample array that has a few duplicates:
115
-
116
-
```
117
-
target = 0
118
-
119
-
[-1, -1, -1, -1, 0, 1, 1, 1]
120
-
```
121
-
122
-
One possible subset is `[-1, 0, 1]`, and in fact is the only subset for 3Sum.
123
-
124
-
The easiet way is using set. We can maintain a solution set, then we can check if the triplets is in the set or not to determine whether it's duplicate.
125
-
126
-
Set introduces space complexity. So we still want to avoid extra space using. Let's change an angle consider, we can loop the array first find `m` then next thing is to find `l` and `r`.
127
-
128
-
For example
129
-
114
+
Since you pre-sort the array, duplicates will be adjacent to each other. You just need to skip over duplicates by comparing adjacent values:
115
+
116
+
```
117
+
extension Collection where Element: Equatable {
118
+
119
+
/// Returns next index with unique value. Works only on sorted arrays.
120
+
///
121
+
/// - Parameter index: The current `Int` index.
122
+
/// - Returns: The new `Int` index. Will return `nil` if new index happens to be the `endIndex` (out of bounds)
123
+
func uniqueIndex(after index: Index) -> Index? {
124
+
guard index < endIndex else { return nil }
125
+
var index = index
126
+
var nextIndex = self.index(after: index)
127
+
while nextIndex < endIndex && self[index] == self[nextIndex] {
128
+
formIndex(after: &index)
129
+
formIndex(after: &nextIndex)
130
+
}
131
+
132
+
if nextIndex == endIndex {
133
+
return nil
134
+
} else {
135
+
return nextIndex
136
+
}
137
+
}
138
+
}
139
+
```
140
+
141
+
A similar implementation is used to get the unique index *before* a given index:
142
+
143
+
```
144
+
extension BidirectionalCollection where Element: Equatable {
145
+
146
+
/// Returns next index with unique value. Works only on sorted arrays.
147
+
///
148
+
/// - Parameter index: The current `Int` index.
149
+
/// - Returns: The new `Int` index. Will return `nil` if new index happens to come before the `startIndex` (out of bounds)
150
+
func uniqueIndex(before index: Index) -> Index? {
151
+
return indices[..<index].reversed().first { index -> Bool in
0 commit comments