55
55
56
56
** 方法一:二分查找**
57
57
58
- 用指针 i 固定第一个数,然后二分查找 ` [i + 1, n - 1 ]` 范围内是否存在 j,使得 ` numbers[j] == target - numbers[i] ` 。
58
+ 注意到数组按照非递减顺序排列,因此对于每个 ` numbers[i] ` ,可以通过二分查找的方式找到 ` target - numbers[i ]` 的位置,如果存在,那么返回 $ [ i + 1, j + 1 ] $ 即可 。
59
59
60
- 时间复杂度 O(nlogn) 。
60
+ 时间复杂度 $O(n \times \log n)$,其中 $n$ 为数组 ` numbers ` 的长度。空间复杂度 $O(1)$ 。
61
61
62
62
** 方法二:双指针**
63
63
64
- 初始时两个指针 i , j 分别指向数组的首尾位置。每次计算两指针对应的两个元素之和 x,判断 x 与 target 的大小关系:
64
+ 我们定义两个指针 $i$ 和 $j$,分别指向数组的第一个元素和最后一个元素。每次计算 $numbers [ i ] + numbers [ j ] $,如果和等于目标值,那么返回 $ [ i + 1 , j + 1 ] $ 即可。如果和小于目标值,那么将 $i$ 右移一位,如果和大于目标值,那么将 $j$ 左移一位。
65
65
66
- - ` x == target ` ,说明找到了答案,返回 ` [i + 1, j + 1] ` ;
67
- - ` x < target ` ,指针 i 右移;
68
- - ` x > target ` ,指针 j 左移。
69
-
70
- 若循环结束后依然没找到答案,则返回 ` [-1, -1] ` 。
71
-
72
- 时间复杂度 $O(n)$。
66
+ 时间复杂度 $O(n)$,其中 $n$ 为数组 ` numbers ` 的长度。空间复杂度 $O(1)$。
73
67
74
68
<!-- tabs:start -->
75
69
76
70
### ** Python3**
77
71
78
72
<!-- 这里可写当前语言的特殊实现逻辑 -->
79
73
80
- 二分查找:
81
-
82
74
``` python
83
75
class Solution :
84
76
def twoSum (self , numbers : List[int ], target : int ) -> List[int ]:
85
77
n = len (numbers)
86
78
for i in range (n - 1 ):
87
79
x = target - numbers[i]
88
- j = bisect. bisect_left(numbers, x, lo = i + 1 )
89
- if j != n and numbers[j] == x:
80
+ j = bisect_left(numbers, x, lo = i + 1 )
81
+ if j < n and numbers[j] == x:
90
82
return [i + 1 , j + 1 ]
91
- return [- 1 , - 1 ]
92
83
```
93
84
94
- 双指针:
95
-
96
85
``` python
97
86
class Solution :
98
87
def twoSum (self , numbers : List[int ], target : int ) -> List[int ]:
99
- i, j = 1 , len (numbers)
88
+ i, j = 0 , len (numbers) - 1
100
89
while i < j:
101
- x = numbers[i - 1 ] + numbers[j - 1 ]
90
+ x = numbers[i] + numbers[j]
102
91
if x == target:
103
- return [i, j]
92
+ return [i + 1 , j + 1 ]
104
93
if x < target:
105
94
i += 1
106
95
else :
107
96
j -= 1
108
- return [- 1 , - 1 ]
109
97
```
110
98
111
99
### ** Java**
112
100
113
101
<!-- 这里可写当前语言的特殊实现逻辑 -->
114
102
115
- 二分查找:
116
-
117
103
``` java
118
104
class Solution {
119
105
public int [] twoSum (int [] numbers , int target ) {
120
- for (int i = 0 , n = numbers. length; i < n - 1 ; ++ i) {
106
+ for (int i = 0 , n = numbers. length;; ++ i) {
121
107
int x = target - numbers[i];
122
- int left = i + 1 , right = n - 1 ;
123
- while (left < right ) {
124
- int mid = (left + right ) >> 1 ;
108
+ int l = i + 1 , r = n - 1 ;
109
+ while (l < r ) {
110
+ int mid = (l + r ) >> 1 ;
125
111
if (numbers[mid] >= x) {
126
- right = mid;
112
+ r = mid;
127
113
} else {
128
- left = mid + 1 ;
114
+ l = mid + 1 ;
129
115
}
130
116
}
131
- if (numbers[left ] == x) {
132
- return new int []{i + 1 , left + 1 };
117
+ if (numbers[l ] == x) {
118
+ return new int [] {i + 1 , l + 1 };
133
119
}
134
120
}
135
- return new int []{- 1 , - 1 };
136
121
}
137
122
}
138
123
```
139
124
140
- 双指针:
141
-
142
125
``` java
143
126
class Solution {
144
127
public int [] twoSum (int [] numbers , int target ) {
145
- int i = 1 , j = numbers. length;
146
- while (i < j) {
147
- int x = numbers[i - 1 ] + numbers[j - 1 ];
128
+ for (int i = 0 , j = numbers. length - 1 ;;) {
129
+ int x = numbers[i] + numbers[j];
148
130
if (x == target) {
149
- return new int [] {i, j};
131
+ return new int [] {i + 1 , j + 1 };
150
132
}
151
133
if (x < target) {
152
134
++ i;
153
135
} else {
154
136
-- j;
155
137
}
156
138
}
157
- return new int [] {- 1 , - 1 };
158
- }
159
- }
160
- ```
161
-
162
- ### ** TypeScript**
163
-
164
- 二分查找:
165
-
166
- ``` ts
167
- function twoSum(numbers : number [], target : number ): number [] {
168
- for (let i = 0 , n = numbers .length ; i < n - 1 ; ++ i ) {
169
- const x = target - numbers [i ];
170
- let left = i + 1 ,
171
- right = n - 1 ;
172
- while (left < right ) {
173
- const mid = (left + right ) >> 1 ;
174
- if (numbers [mid ] >= x ) {
175
- right = mid ;
176
- } else {
177
- left = mid + 1 ;
178
- }
179
- }
180
- if (numbers [left ] == x ) {
181
- return [i + 1 , left + 1 ];
182
- }
183
139
}
184
- return [- 1 , - 1 ];
185
- }
186
- ```
187
-
188
- 双指针:
189
-
190
- ``` ts
191
- function twoSum(numbers : number [], target : number ): number [] {
192
- let i = 1 ,
193
- j = numbers .length ;
194
- while (i < j ) {
195
- const x = numbers [i - 1 ] + numbers [j - 1 ];
196
- if (x == target ) {
197
- return [i , j ];
198
- }
199
- if (x < target ) {
200
- ++ i ;
201
- } else {
202
- -- j ;
203
- }
204
- }
205
- return [- 1 , - 1 ];
206
140
}
207
141
```
208
142
209
143
### ** C++**
210
144
211
- 二分查找:
212
-
213
145
``` cpp
214
146
class Solution {
215
147
public:
216
148
vector<int > twoSum(vector<int >& numbers, int target) {
217
- for (int i = 0, n = numbers.size(); i < n - 1 ; ++i) {
149
+ for (int i = 0, n = numbers.size();; ++i) {
218
150
int x = target - numbers[ i] ;
219
151
int j = lower_bound(numbers.begin() + i + 1, numbers.end(), x) - numbers.begin();
220
- if (j != n && numbers[ j] == x) return {i + 1, j + 1};
152
+ if (j < n && numbers[ j] == x) {
153
+ return {i + 1, j + 1};
154
+ }
221
155
}
222
- return {-1, -1};
223
156
}
224
157
};
225
158
```
226
159
227
- 双指针:
228
-
229
160
```cpp
230
161
class Solution {
231
162
public:
232
163
vector<int> twoSum(vector<int>& numbers, int target) {
233
- int i = 1, j = numbers.size();
234
- while (i < j)
235
- {
236
- int x = numbers[i - 1] + numbers[j - 1];
237
- if (x == target) return {i, j};
238
- if (x < target) ++i;
239
- else --j;
164
+ for (int i = 0, j = numbers.size() - 1;;) {
165
+ int x = numbers[i] + numbers[j];
166
+ if (x == target) {
167
+ return {i + 1, j + 1};
168
+ }
169
+ if (x < target) {
170
+ ++i;
171
+ } else {
172
+ --j;
173
+ }
240
174
}
241
- return {-1, -1};
242
175
}
243
176
};
244
177
```
245
178
246
179
### ** Go**
247
180
248
- 二分查找:
249
-
250
181
``` go
251
182
func twoSum (numbers []int , target int ) []int {
252
- for i , n := 0 , len (numbers); i < n- 1 ; i++ {
183
+ for i , n := 0 , len (numbers); ; i++ {
253
184
x := target - numbers[i]
254
- left , right := i+1 , n-1
255
- for left < right {
256
- mid := (left + right) >> 1
257
- if numbers[mid] >= x {
258
- right = mid
259
- } else {
260
- left = mid + 1
261
- }
262
- }
263
- if numbers[left] == x {
264
- return []int {i + 1 , left + 1 }
185
+ j := sort.SearchInts (numbers[i+1 :], x) + i + 1
186
+ if j < n && numbers[j] == x {
187
+ return []int {i + 1 , j + 1 }
265
188
}
266
189
}
267
- return []int {-1 , -1 }
268
190
}
269
191
```
270
192
271
- 双指针:
272
-
273
193
``` go
274
194
func twoSum (numbers []int , target int ) []int {
275
- i , j := 1 , len (numbers)
276
- for i < j {
277
- x := numbers[i-1 ] + numbers[j-1 ]
195
+ for i , j := 0 , len (numbers)-1 ; ; {
196
+ x := numbers[i] + numbers[j]
278
197
if x == target {
279
- return []int {i, j}
198
+ return []int {i + 1 , j + 1 }
280
199
}
281
200
if x < target {
282
201
i++
283
202
} else {
284
203
j--
285
204
}
286
205
}
287
- return []int {-1 , -1 }
288
206
}
289
207
```
290
208
291
- ### ** JavaScript**
209
+ ### ** TypeScript**
210
+
211
+ ``` ts
212
+ function twoSum(numbers : number [], target : number ): number [] {
213
+ const n = numbers .length ;
214
+ for (let i = 0 ; ; ++ i ) {
215
+ const x = target - numbers [i ];
216
+ let l = i + 1 ;
217
+ let r = n - 1 ;
218
+ while (l < r ) {
219
+ const mid = (l + r ) >> 1 ;
220
+ if (numbers [mid ] >= x ) {
221
+ r = mid ;
222
+ } else {
223
+ l = mid + 1 ;
224
+ }
225
+ }
226
+ if (numbers [l ] === x ) {
227
+ return [i + 1 , l + 1 ];
228
+ }
229
+ }
230
+ }
231
+ ```
292
232
293
- 二分查找:
233
+ ``` ts
234
+ function twoSum(numbers : number [], target : number ): number [] {
235
+ for (let i = 0 , j = numbers .length - 1 ; ; ) {
236
+ const x = numbers [i ] + numbers [j ];
237
+ if (x === target ) {
238
+ return [i + 1 , j + 1 ];
239
+ }
240
+ if (x < target ) {
241
+ ++ i ;
242
+ } else {
243
+ -- j ;
244
+ }
245
+ }
246
+ }
247
+ ```
248
+
249
+ ### ** JavaScript**
294
250
295
251
``` js
296
252
/**
@@ -299,49 +255,44 @@ func twoSum(numbers []int, target int) []int {
299
255
* @return {number[]}
300
256
*/
301
257
var twoSum = function (numbers , target ) {
302
- for (let i = 0 , n = numbers .length ; i < n - 1 ; ++ i) {
258
+ const n = numbers .length ;
259
+ for (let i = 0 ; ; ++ i) {
303
260
const x = target - numbers[i];
304
- let left = i + 1 ,
305
- right = n - 1 ;
306
- while (left < right ) {
307
- const mid = (left + right ) >> 1 ;
261
+ let l = i + 1 ;
262
+ let r = n - 1 ;
263
+ while (l < r ) {
264
+ const mid = (l + r ) >> 1 ;
308
265
if (numbers[mid] >= x) {
309
- right = mid;
266
+ r = mid;
310
267
} else {
311
- left = mid + 1 ;
268
+ l = mid + 1 ;
312
269
}
313
270
}
314
- if (numbers[left] == x) {
315
- return [i + 1 , left + 1 ];
271
+ if (numbers[l] = == x) {
272
+ return [i + 1 , l + 1 ];
316
273
}
317
274
}
318
- return [- 1 , - 1 ];
319
275
};
320
276
```
321
277
322
- 双指针:
323
-
324
278
``` js
325
279
/**
326
280
* @param {number[]} numbers
327
281
* @param {number} target
328
282
* @return {number[]}
329
283
*/
330
284
var twoSum = function (numbers , target ) {
331
- let i = 1 ,
332
- j = numbers .length ;
333
- while (i < j) {
334
- const x = numbers[i - 1 ] + numbers[j - 1 ];
335
- if (x == target) {
336
- return [i, j];
285
+ for (let i = 0 , j = numbers .length - 1 ; ; ) {
286
+ const x = numbers[i] + numbers[j];
287
+ if (x === target) {
288
+ return [i + 1 , j + 1 ];
337
289
}
338
290
if (x < target) {
339
291
++ i;
340
292
} else {
341
293
-- j;
342
294
}
343
295
}
344
- return [- 1 , - 1 ];
345
296
};
346
297
```
347
298
0 commit comments