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: Two-Sum Problem/README.markdown
+71Lines changed: 71 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -4,12 +4,21 @@ Given an array of integers and an integer target, return the indices of two numb
4
4
5
5
There are a variety of solutions to this problem (some better than others). The following solutions both run in **O(n)** time.
6
6
7
+
给定一个整数数组和一个整数目标,返回与目标相加的两个数字的索引。
8
+
9
+
这个问题有很多解决方案(有些比其他解决方案更好)。 以下解决方案均在**O(n)**时间内运行。
10
+
7
11
# Solution 1
12
+
# 解决方案1
8
13
9
14
This solution looks at one number at a time, storing each number in the dictionary. It uses the number as the key and the number's index in the array as the value.
10
15
11
16
For each number n, we know the complementing number to sum up to the target is `target - n`. By looking up the complement in the dictionary, we'd know whether we've seen the complement before and what its index is.
Is the complement `1` in the dictionary? No, so we add `9` and its index `2` to the dictionary.:
85
+
字典中的补码是`1`吗? 不,所以我们将`9`及其索引`2`添加到字典中:
66
86
67
87
```swift
68
88
[3:0, 2:1, 9:2]
@@ -78,12 +98,26 @@ If the given array has multiple solutions, only the first solution is returned.
78
98
79
99
The running time of this algorithm is **O(n)** because it may look at every element in the array. It also requires **O(n)** additional storage space for the dictionary.
**Note**: This particular algorithm requires that the array is sorted, so if the array isn't sorted yet (usually it won't be), you need to sort it first. The time complexity of the algorithm itself is **O(n)** and, unlike the previous solution, it does not require extra storage. Of course, if you have to sort first, the total time complexity becomes **O(n log n)**. Slightly worse but still quite acceptable.
The algorithm uses the two variables `i` and `j` to point to the beginning and end of the array, respectively. Then it increments `i` and decrements `j` until the two meet. While it's doing this, it checks whether `a[i]` and `a[j]` add up to `k`.
The sum of these two is `2 + 100 = 102`. That's obviously too much, since `k = 33` in this example. There is no way that `100` will ever be part of the answer, so decrement `j`.
The sum is `2 + 22 = 24`. Now the sum is too small. We can safely conclude at this point that the number `2` will never be part of the answer. The largest number on the right is `22`, so we at least need `11` on the left to make `33`. Anything less than `11` is not going to cut it. (This is why we sorted the array!)
140
194
141
195
So, `2` is out and we increment `i` to look at the next small number.
The sum is `3 + 22 = 25`. Still too small, so increment `i` again.
205
+
总和是`3 + 22 = 25`。 还是太小了,所以再次增加`i`。
147
206
148
207
[ 2, 3, 4, 4, 7, 8, 9, 10, 12, 14, 21, 22, 100 ]
149
208
i j
150
209
151
210
In fact, we have to increment `i` a few more times, until we get to `12`:
211
+
事实上,我们必须再增加几次`i`,直到我们达到`12`:
152
212
153
213
[ 2, 3, 4, 4, 7, 8, 9, 10, 12, 14, 21, 22, 100 ]
154
214
i j
155
215
156
216
Now the sum is `12 + 22 = 34`. It's too high, which means we need to decrement `j`. This gives:
217
+
现在总和是`12 + 22 = 34`。 它太高了,这意味着我们需要减少`j`。 这给出了:
157
218
158
219
[ 2, 3, 4, 4, 7, 8, 9, 10, 12, 14, 21, 22, 100 ]
159
220
i j
@@ -164,8 +225,18 @@ It's possible, of course, that there are no values for `a[i] + a[j]` that sum to
164
225
165
226
I'm quite enamored by this little algorithm. It shows that with some basic preprocessing on the input data -- sorting it from low to high -- you can turn a tricky problem into a very simple and beautiful algorithm.
Given an array of integers and an integer target, return the indices of two numbers that add up to the target.
4
+
5
+
There are a variety of solutions to this problem (some better than others). The following solutions both run in **O(n)** time.
6
+
7
+
# Solution 1
8
+
9
+
This solution looks at one number at a time, storing each number in the dictionary. It uses the number as the key and the number's index in the array as the value.
10
+
11
+
For each number n, we know the complementing number to sum up to the target is `target - n`. By looking up the complement in the dictionary, we'd know whether we've seen the complement before and what its index is.
// Find the complement to n that would sum up to the target.
20
+
let complement = target - n
21
+
22
+
// Check if the complement is in the dictionary.
23
+
iflet complementIndex = dict[complement] {
24
+
return (complementIndex, currentIndex)
25
+
}
26
+
27
+
// Store n and its index into the dictionary.
28
+
dict[n] = currentIndex
29
+
}
30
+
31
+
returnnil
32
+
}
33
+
```
34
+
35
+
The `twoSum` function takes two parameters: the `numbers` array and the target sum. It returns the two indicies of the pair of elements that sums up to the target, or `nil` if they can't be found.
36
+
37
+
Let's run through the algorithm to see how it works. Given the array:
38
+
39
+
```swift
40
+
[3, 2, 9, 8]
41
+
```
42
+
43
+
Let's find out if there exist two entries whose sum is 10.
44
+
45
+
Initially, our dictionary is empty. We begin looping through each element:
Is the complement `2` in the dictionary? Yes! That means that we have found a pair of entries that sum to the target!
74
+
75
+
Therefore, the `complementIndex = dict[2] = 1` and the `currentIndex = 3`. The tuple we return is `(1, 3)`.
76
+
77
+
If the given array has multiple solutions, only the first solution is returned.
78
+
79
+
The running time of this algorithm is **O(n)** because it may look at every element in the array. It also requires **O(n)** additional storage space for the dictionary.
80
+
81
+
# Solution 2
82
+
83
+
**Note**: This particular algorithm requires that the array is sorted, so if the array isn't sorted yet (usually it won't be), you need to sort it first. The time complexity of the algorithm itself is **O(n)** and, unlike the previous solution, it does not require extra storage. Of course, if you have to sort first, the total time complexity becomes **O(n log n)**. Slightly worse but still quite acceptable.
As in the first solution, the `twoSumProblem()` function takes as parameters the array `a` with the numbers and `k`, the sum we're looking for. If there are two numbers that add up to `k`, the function returns a tuple containing their array indices. If not, it returns `nil`. The main difference is that `a` is assumed to be sorted.
107
+
108
+
To test it, copy the code into a playground and add the following:
109
+
110
+
```swift
111
+
let a = [2, 3, 4, 4, 7, 8, 9, 10, 12, 14, 21, 22, 100]
112
+
iflet (i, j) =twoSumProblem(a, k: 33) {
113
+
a[i] + a[j] // 33
114
+
}
115
+
```
116
+
117
+
This returns the tuple `(8, 10)` because `a[8] = 12` and `a[10] = 21`, and together they add up to `33`.
118
+
119
+
So how does this algorithm work? It takes advantage of the array being sorted. That's true for many algorithms, by the way. If you first sort the data, it's often easier to perform your calculations.
120
+
121
+
In the example, the sorted array is:
122
+
123
+
[ 2, 3, 4, 4, 7, 8, 9, 10, 12, 14, 21, 22, 100 ]
124
+
125
+
The algorithm uses the two variables `i` and `j` to point to the beginning and end of the array, respectively. Then it increments `i` and decrements `j` until the two meet. While it's doing this, it checks whether `a[i]` and `a[j]` add up to `k`.
126
+
127
+
Let's step through this. Initially, we have:
128
+
129
+
[ 2, 3, 4, 4, 7, 8, 9, 10, 12, 14, 21, 22, 100 ]
130
+
i j
131
+
132
+
The sum of these two is `2 + 100 = 102`. That's obviously too much, since `k = 33` in this example. There is no way that `100` will ever be part of the answer, so decrement `j`.
133
+
134
+
We have:
135
+
136
+
[ 2, 3, 4, 4, 7, 8, 9, 10, 12, 14, 21, 22, 100 ]
137
+
i j
138
+
139
+
The sum is `2 + 22 = 24`. Now the sum is too small. We can safely conclude at this point that the number `2` will never be part of the answer. The largest number on the right is `22`, so we at least need `11` on the left to make `33`. Anything less than `11` is not going to cut it. (This is why we sorted the array!)
140
+
141
+
So, `2` is out and we increment `i` to look at the next small number.
142
+
143
+
[ 2, 3, 4, 4, 7, 8, 9, 10, 12, 14, 21, 22, 100 ]
144
+
i j
145
+
146
+
The sum is `3 + 22 = 25`. Still too small, so increment `i` again.
147
+
148
+
[ 2, 3, 4, 4, 7, 8, 9, 10, 12, 14, 21, 22, 100 ]
149
+
i j
150
+
151
+
In fact, we have to increment `i` a few more times, until we get to `12`:
152
+
153
+
[ 2, 3, 4, 4, 7, 8, 9, 10, 12, 14, 21, 22, 100 ]
154
+
i j
155
+
156
+
Now the sum is `12 + 22 = 34`. It's too high, which means we need to decrement `j`. This gives:
157
+
158
+
[ 2, 3, 4, 4, 7, 8, 9, 10, 12, 14, 21, 22, 100 ]
159
+
i j
160
+
161
+
And finally, we have the answer: `12 + 21 = 33`. Yay!
162
+
163
+
It's possible, of course, that there are no values for `a[i] + a[j]` that sum to `k`. In that case, eventually `i` and `j` will point at the same number. Then we can conclude that no answer exists and we return `nil`.
164
+
165
+
I'm quite enamored by this little algorithm. It shows that with some basic preprocessing on the input data -- sorting it from low to high -- you can turn a tricky problem into a very simple and beautiful algorithm.
0 commit comments