1
+ 原始链接:[ 力扣题解最佳实践 - 力扣人] ( https://leetcoder.net/zh/leetcode/1-two-sum )
2
+
1
3
#1. 两数之和 - 力扣题解最佳实践
2
4
力扣链接:[ 1. 两数之和] ( https://leetcode.cn/problems/two-sum ) ,难度:** 简单** 。
3
5
4
- ##力扣“1. 两数之和”问题描述
6
+ ##力扣题目描述
5
7
给定一个整数数组` nums ` 和一个整数目标值` target ` ,请你在该数组中找出** 和为目标值** ` target ` 的那** 两个** 整数,并返回它们的数组下标。
6
8
7
9
你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。
26
28
** 输出** :` [0,1] `
27
29
28
30
###[ 约束]
29
- - ` 2 <= nums.length <=10000 `
31
+ - ` 2 <= nums.length <=10^4 `
30
32
- ` -10^9 <= nums[i] <= 10^9 `
33
+ - ` -10^9 <= target <= 10^9 `
31
34
- ** 只会存在一个有效答案**
32
35
33
36
###[ 提示]
34
- < details >
35
- < summary >提示 1</ summary >
37
+ 提示 1
38
+
36
39
A really brute force way would be to search for all possible pairs of numbers but that would be too slow. Again, it's best to try out brute force solutions for just for completeness. It is from these brute force solutions that you can come up with optimizations.
37
- </details >
38
40
39
- <details >
40
- <summary >提示 2</summary >
41
+ ---
42
+
43
+ 提示 2
44
+
41
45
So, if we fix one of the numbers, say` x ` , we have to scan the entire array to find the next number` y ` which is` value - x ` where value is the input parameter. Can we change our array somehow so that this search becomes faster?
42
- </details >
43
46
44
- <details >
45
- <summary >提示 3</summary >
47
+ ---
48
+
49
+ 提示 3
50
+
46
51
The second train of thought is, without changing the array, can we use additional space somehow? Like maybe a hash map to speed up the search?
47
- </details >
48
52
49
- ##思路
50
- ### 思路1:双指针
53
+ ##思路 1
54
+
51
55
1 . 暴力解法的时间复杂度为` O(n**2) ` ,想提升效率,可以对数组进行排序,然后用双指针,一个指向数组头,一个指向数组尾,根据** 和** 情况决定` left += 1 ` 还是` right -= 1 ` 。
52
56
53
- 2 . 对数值数组排序后,想知道某个数值对应的原来的索引下标,有两种方案 :
57
+ 2 . 对数字数组排序后,如果想知道某个值对应的原始 ` index ` ,有两种解决方案 :
54
58
55
- - 方案1:使用index() 查找;
56
- - 方案2:在排序时带上索引下标,即排序的对象是元组 ` (num, index) ` 的数组 。
59
+ - 方案1:排序时带上 ` index ` ,即排序的对象是 ` (num, index) ` 的元组数组。这个技巧 ** 必须掌握 ** ,因为很多题目都会用到。
60
+ - 方案2:用 ` index() ` 方法去找。我在另一个解法中讨论过这个问题 。
57
61
58
- ###思路2:使用 Map 提升查找一个值的效率
59
- 1 . ` Map ` 中,` key ` 是` num ` ,` value ` 是数组` index ` 。
60
- 2 . 遍历数组,如果` target - num ` 在` Map ` 中,返回。反之,将` num ` 加入` Map ` 中。
62
+ ##复杂度
61
63
62
- #### 步骤
63
- 1 . ` Map ` 中, ` key ` 是 ` num ` , ` value ` 是数组 ` index ` 。
64
+ - 时间复杂度: ` O(N * log N) ` 。
65
+ - 空间复杂度: ` O(N) ` 。
64
66
65
- ``` javascript
66
- let numToIndex= new Map ()
67
-
68
- for (let i= 0 ; i< nums .length ; i++ ) {
69
- numToIndex .set (nums[i], i)
70
- }
71
- ```
72
-
73
- 2. 遍历数组,如果` target - num` 在` Map` 中,返回。反之,将` num` 加入` Map` 中。
74
-
75
- ` ` ` javascript
76
- let numToIndex = new Map()
77
-
78
- for (let i = 0; i < nums.length; i++) {
79
- if (numToIndex.has(target - nums[i])) { // 1
80
- return [numToIndex.get(target - nums[i]), i] // 2
81
- }
82
-
83
- numToIndex.set(nums[i], i)
84
- }
85
- ` ` `
67
+ ##Python
86
68
87
- ## 复杂度
88
- * 时间:` O(n)` 。
89
- * 空间:` O(n)` 。
69
+ ``` python
70
+ class Solution :
71
+ def twoSum (self ,nums : List[int ],target :int ) -> List[int ]:
72
+ num_index_list= [(num, i)for i, numin enumerate (nums)]
73
+ num_index_list.sort()
74
+
75
+ left= 0
76
+ right= len (nums)- 1
77
+
78
+ while left< right:
79
+ sum_= num_index_list[left][0 ]+ num_index_list[right][0 ]
80
+
81
+ if sum_== target:
82
+ return [num_index_list[left][1 ], num_index_list[right][1 ]]
83
+
84
+ if sum_< target:
85
+ left+= 1
86
+ continue
87
+
88
+ right-= 1
89
+ ```
90
+
91
+ ##其他语言
90
92
91
- ## Java
92
- ### Solution1 : Two pointers
93
93
``` java
94
- //Welcome to create a PRto complete the code, thanks!
94
+ // 欢迎提交 PR来完成这个语言的代码,谢谢!
95
95
```
96
96
97
- ### Solution2 : UsingMap
97
+ ##思路 2
98
+
99
+ 1 . 在` Map ` 中,` key ` 是` num ` ,` value ` 是数组` index ` 。
100
+ 2 . 遍历数组,如果` target - num ` 在` Map ` 中,就返回它。否则,把` num ` 加入` Map ` 。
101
+
102
+ ##步骤
103
+
104
+ 1 . 在` Map ` 中,` key ` 是` num ` ,` value ` 是数组` index ` 。
105
+
106
+ ``` javascript
107
+ let numToIndex= new Map ()
108
+ for (let i= 0 ; i< nums .length ; i++ ) {
109
+ numToIndex .set (nums[i], i)
110
+ }
111
+ ```
112
+
113
+ 2 . 遍历数组,如果` target - num ` 在` Map ` 中,就返回它。否则,把` num ` 加入` Map ` 。
114
+
115
+ ``` javascript
116
+ let numToIndex= new Map ()
117
+ for (let i= 0 ; i< nums .length ; i++ ) {
118
+ if (numToIndex .has (target- nums[i])) {// 1
119
+ return [numToIndex .get (target- nums[i]), i]// 2
120
+ }
121
+ numToIndex .set (nums[i], i)
122
+ }
123
+ ```
124
+
125
+ ##复杂度
126
+
127
+ - 时间复杂度:` O(N) ` 。
128
+ - 空间复杂度:` O(N) ` 。
129
+
130
+ ##Java
131
+
98
132
``` java
99
133
class Solution {
100
134
public int []twoSum (int []nums ,int target ) {
101
135
var numToIndex= new HashMap<Integer ,Integer > ();
102
-
136
+
103
137
for (var i= 0 ; i< nums. length; i++ ) {
104
138
if (numToIndex. containsKey(target- nums[i])) {
105
139
return new int []{numToIndex. get(target- nums[i]), i};
@@ -114,37 +148,12 @@ class Solution {
114
148
```
115
149
116
150
##Python
117
- ### Solution1 : Two pointers
118
- ` ` ` python
119
- class Solution:
120
- def twoSum(self, nums: List[int], target: int) -> List[int]:
121
- original_nums = nums.copy()
122
- nums.sort()
123
151
124
- left = 0
125
- right = len(nums) - 1
126
-
127
- while left < right:
128
- sum_ = nums[left] + nums[right]
129
-
130
- if sum_ == target:
131
- break
132
-
133
- if sum_ < target:
134
- left += 1
135
- continue
136
-
137
- right -= 1
138
-
139
- return [original_nums.index(nums[left]), len(nums) - 1 - original_nums[::-1].index(nums[right])]
140
- ` ` `
141
-
142
- ### Solution2 : UsingMap
143
152
``` python
144
153
class Solution :
145
154
def twoSum (self ,nums : List[int ],target :int ) -> List[int ]:
146
155
num_to_index= {}
147
-
156
+
148
157
for i, numin enumerate (nums):
149
158
if target- numin num_to_index:
150
159
return [num_to_index[target- num], i]
@@ -153,18 +162,13 @@ class Solution:
153
162
```
154
163
155
164
##C++
156
- ### Solution1 : Two pointers
157
- ` ` ` cpp
158
- // Welcome to create a PR to complete the code, thanks!
159
- ` ` `
160
165
161
- ### Solution2 : UsingMap
162
166
``` cpp
163
167
class Solution {
164
168
public:
165
169
vector<int > twoSum(vector<int >& nums, int target) {
166
170
unordered_map<int, int> num_to_index;
167
-
171
+
168
172
for (auto i = 0; i < nums.size(); i++) {
169
173
if (num_to_index.contains(target - nums[i])) {
170
174
return {num_to_index[target - nums[i]], i};
@@ -179,16 +183,11 @@ public:
179
183
```
180
184
181
185
##JavaScript
182
- ### Solution1 : Two pointers
183
- ` ` ` javascript
184
- // Welcome to create a PR to complete the code, thanks!
185
- ` ` `
186
186
187
- ### Solution2 : UsingMap
188
187
``` javascript
189
188
var twoSum = function (nums ,target ) {
190
189
let numToIndex= new Map ()
191
-
190
+
192
191
for (let i= 0 ; i< nums .length ; i++ ) {
193
192
if (numToIndex .has (target- nums[i])) {
194
193
return [numToIndex .get (target- nums[i]), i]
@@ -200,17 +199,12 @@ var twoSum = function (nums, target) {
200
199
```
201
200
202
201
##C#
203
- ### Solution1 : Two pointers
204
- ` ` ` c#
205
- // Welcome to create a PR to complete the code, thanks!
206
- ` ` `
207
202
208
- ### Solution2 : UsingMap
209
203
``` c#
210
204
public class Solution {
211
205
public int []TwoSum (int []nums ,int target ) {
212
206
var numToIndex = new Dictionary <int ,int >();
213
-
207
+
214
208
for (int i = 0 ;i < nums .Length ;i ++ ) {
215
209
if (numToIndex .ContainsKey (target - nums [i ])) {
216
210
return [numToIndex [target - nums [i ]],i ];
@@ -225,12 +219,7 @@ public class Solution {
225
219
```
226
220
227
221
##Go
228
- ### Solution1 : Two pointers
229
- ` ` ` go
230
- // Welcome to create a PR to complete the code, thanks!
231
- ` ` `
232
222
233
- ### Solution2 : UsingMap
234
223
``` go
235
224
func twoSum (nums []int ,target int ) []int {
236
225
numToIndex := map [int ]int {}
@@ -248,12 +237,7 @@ func twoSum(nums []int, target int) []int {
248
237
```
249
238
250
239
##Ruby
251
- ### Solution1 : Two pointers
252
- ` ` ` ruby
253
- # Welcome to create a PR to complete the code, thanks!
254
- ` ` `
255
240
256
- ### Solution2 : UsingMap
257
241
``` ruby
258
242
def two_sum (nums ,target )
259
243
num_to_index= {}
@@ -268,27 +252,54 @@ def two_sum(nums, target)
268
252
end
269
253
```
270
254
271
- ##C
272
- ` ` ` c
273
- // Welcome to create a PR to complete the code of this language, thanks!
274
- ` ` `
255
+ ##其他语言
275
256
276
- ## Kotlin
277
- ` ` ` kotlin
278
- // Welcome to create a PR to complete the code of this language, thanks!
257
+ ``` java
258
+ // 欢迎提交 PR 来完成这个语言的代码,谢谢!
279
259
```
280
260
281
- ## Swift
282
- ` ` ` swift
283
- // Welcome to create a PR to complete the code of this language, thanks!
284
- ` ` `
261
+ ##思路 3
285
262
286
- ## Rust
287
- ` ` ` rust
288
- // Welcome to create a PR to complete the code of this language, thanks!
289
- ` ` `
263
+ 1 . 暴力解法的时间复杂度为` O(n^2) ` ,想提升效率,可以对数组进行排序,然后用双指针,一个指向数组头,一个指向数组尾,根据** 和** 情况决定` left += 1 ` 还是` right -= 1 ` 。
290
264
291
- ## Other languages
265
+ 2 . 找出了两个值后,需要用` index() ` 方法去找值对应的` index ` 。
266
+
267
+ ##复杂度
268
+
269
+ - 时间复杂度:` O(N * log N) ` 。
270
+ - 空间复杂度:` O(N) ` 。
271
+
272
+ ##Python
273
+
274
+ ``` python
275
+ class Solution :
276
+ def twoSum (self ,nums : List[int ],target :int ) -> List[int ]:
277
+ original_nums= nums.copy()
278
+ nums.sort()
279
+
280
+ left= 0
281
+ right= len (nums)- 1
282
+
283
+ while left< right:
284
+ sum_= nums[left]+ nums[right]
285
+
286
+ if sum_== target:
287
+ break
288
+
289
+ if sum_< target:
290
+ left+= 1
291
+ continue
292
+
293
+ right-= 1
294
+
295
+ return [
296
+ original_nums.index(nums[left]),
297
+ len (nums)- 1 - original_nums[::- 1 ].index(nums[right])
298
+ ]
292
299
```
293
- // Welcome to create a PR to complete the code of this language, thanks!
300
+
301
+ ##其他语言
302
+
303
+ ``` java
304
+ // 欢迎提交 PR 来完成这个语言的代码,谢谢!
294
305
```