Skip to content

Commit 6df0a39

Browse files
committed
feat: add solutions to lc problem: No.0167
No.0167.Two Sum II - Input Array Is Sorted
1 parent 917e088 commit 6df0a39

File tree

8 files changed

+225
-315
lines changed

8 files changed

+225
-315
lines changed

solution/0100-0199/0167.Two Sum II - Input Array Is Sorted/README.md

Lines changed: 95 additions & 144 deletions
Original file line numberDiff line numberDiff line change
@@ -55,242 +55,198 @@
5555

5656
**方法一:二分查找**
5757

58-
用指针 i 固定第一个数,然后二分查找 `[i + 1, n - 1]` 范围内是否存在 j,使得 `numbers[j] == target - numbers[i]`
58+
注意到数组按照非递减顺序排列,因此对于每个 `numbers[i]`,可以通过二分查找的方式找到 `target - numbers[i]` 的位置,如果存在,那么返回 $[i + 1, j + 1]$ 即可
5959

60-
时间复杂度 O(nlogn)
60+
时间复杂度 $O(n \times \log n)$,其中 $n$ 为数组 `numbers` 的长度。空间复杂度 $O(1)$
6161

6262
**方法二:双指针**
6363

64-
初始时两个指针 i, j 分别指向数组的首尾位置。每次计算两指针对应的两个元素之和 x,判断 x 与 target 的大小关系:
64+
我们定义两个指针 $i$ 和 $j$,分别指向数组的第一个元素和最后一个元素。每次计算 $numbers[i] + numbers[j]$,如果和等于目标值,那么返回 $[i + 1, j + 1]$ 即可。如果和小于目标值,那么将 $i$ 右移一位,如果和大于目标值,那么将 $j$ 左移一位。
6565

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)$。
7367

7468
<!-- tabs:start -->
7569

7670
### **Python3**
7771

7872
<!-- 这里可写当前语言的特殊实现逻辑 -->
7973

80-
二分查找:
81-
8274
```python
8375
class Solution:
8476
def twoSum(self, numbers: List[int], target: int) -> List[int]:
8577
n = len(numbers)
8678
for i in range(n - 1):
8779
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:
9082
return [i + 1, j + 1]
91-
return [-1, -1]
9283
```
9384

94-
双指针:
95-
9685
```python
9786
class Solution:
9887
def twoSum(self, numbers: List[int], target: int) -> List[int]:
99-
i, j = 1, len(numbers)
88+
i, j = 0, len(numbers) - 1
10089
while i < j:
101-
x = numbers[i - 1] + numbers[j - 1]
90+
x = numbers[i] + numbers[j]
10291
if x == target:
103-
return [i, j]
92+
return [i + 1, j + 1]
10493
if x < target:
10594
i += 1
10695
else:
10796
j -= 1
108-
return [-1, -1]
10997
```
11098

11199
### **Java**
112100

113101
<!-- 这里可写当前语言的特殊实现逻辑 -->
114102

115-
二分查找:
116-
117103
```java
118104
class Solution {
119105
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) {
121107
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;
125111
if (numbers[mid] >= x) {
126-
right = mid;
112+
r = mid;
127113
} else {
128-
left = mid + 1;
114+
l = mid + 1;
129115
}
130116
}
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};
133119
}
134120
}
135-
return new int[]{-1, -1};
136121
}
137122
}
138123
```
139124

140-
双指针:
141-
142125
```java
143126
class Solution {
144127
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];
148130
if (x == target) {
149-
return new int[] {i, j};
131+
return new int[] {i + 1, j + 1};
150132
}
151133
if (x < target) {
152134
++i;
153135
} else {
154136
--j;
155137
}
156138
}
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-
}
183139
}
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];
206140
}
207141
```
208142

209143
### **C++**
210144

211-
二分查找:
212-
213145
```cpp
214146
class Solution {
215147
public:
216148
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) {
218150
int x = target - numbers[i];
219151
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+
}
221155
}
222-
return {-1, -1};
223156
}
224157
};
225158
```
226159
227-
双指针:
228-
229160
```cpp
230161
class Solution {
231162
public:
232163
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+
}
240174
}
241-
return {-1, -1};
242175
}
243176
};
244177
```
245178

246179
### **Go**
247180

248-
二分查找:
249-
250181
```go
251182
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++ {
253184
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}
265188
}
266189
}
267-
return []int{-1, -1}
268190
}
269191
```
270192

271-
双指针:
272-
273193
```go
274194
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]
278197
if x == target {
279-
return []int{i, j}
198+
return []int{i + 1, j + 1}
280199
}
281200
if x < target {
282201
i++
283202
} else {
284203
j--
285204
}
286205
}
287-
return []int{-1, -1}
288206
}
289207
```
290208

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+
```
292232

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**
294250

295251
```js
296252
/**
@@ -299,49 +255,44 @@ func twoSum(numbers []int, target int) []int {
299255
* @return {number[]}
300256
*/
301257
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) {
303260
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;
308265
if (numbers[mid] >= x) {
309-
right = mid;
266+
r = mid;
310267
} else {
311-
left = mid + 1;
268+
l = mid + 1;
312269
}
313270
}
314-
if (numbers[left] == x) {
315-
return [i + 1, left + 1];
271+
if (numbers[l] === x) {
272+
return [i + 1, l + 1];
316273
}
317274
}
318-
return [-1, -1];
319275
};
320276
```
321277

322-
双指针:
323-
324278
```js
325279
/**
326280
* @param {number[]} numbers
327281
* @param {number} target
328282
* @return {number[]}
329283
*/
330284
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];
337289
}
338290
if (x < target) {
339291
++i;
340292
} else {
341293
--j;
342294
}
343295
}
344-
return [-1, -1];
345296
};
346297
```
347298

0 commit comments

Comments
 (0)