|
4 | 4 |
|
5 | 5 | ## 3Sum
|
6 | 6 |
|
7 |
| -Given an array of integers, find all subsets of the array with 3 values where the 3 values sum up to a target number. |
| 7 | +> Given an array of integers, find all subsets of the array with 3 values where the 3 values sum up to a target number. |
8 | 8 |
|
9 |
| -**Note**: The solution subsets must not contain duplicate triplets. (Each element in the array can only be used once) |
| 9 | +> **Note**: The solution subsets must not contain duplicate triplets. |
10 | 10 |
|
11 | 11 | > For example, given the array [-1, 0, 1, 2, -1, -4], and the target **0**:
|
12 | 12 | > The solution set is: [[-1, 0, 1], [-1, -1, 2]] // The two **-1** values in the array are considered to be distinct
|
13 | 13 |
|
14 |
| -### Example |
| 14 | +There are 3 key procedures in solving this algorithm: |
15 | 15 |
|
16 |
| -Consider the following array of integers, and a target sum of **0**: |
| 16 | +1. Sort the array in ascending order. This allows you to make smart decisions when moving indexes around (since duplicates will be adjacent to each other). |
17 | 17 |
|
18 |
| -``` |
19 |
| -[-1, 0, 1, 2, -1, -4] |
20 |
| -``` |
21 |
| - |
22 |
| -#### 1. Sorting |
23 |
| - |
24 |
| -You'll first sort the array in ascending order: |
25 |
| - |
26 |
| -``` |
27 |
| -[-4, -1, -1, 0, 1, 2] |
28 |
| -``` |
29 |
| - |
30 |
| -#### 2. Two Sum's Methodology |
31 |
| - |
32 |
| -The 3Sum problem can be solved by augmenting the 2Sum solution, so let's begin by doing a quick explanation on how 2Sum handles the solution. 2Sum begins by comparing the left and right most values: |
33 |
| - |
34 |
| -``` |
35 |
| -[-4, -1, -1, 0, 1, 2] |
36 |
| - l r |
37 |
| -``` |
38 |
| - |
39 |
| -Your target sum is **0**. Given the current left and right values, you won't be able to make the target number. However, you've gained a valuable hint for your next step. |
40 |
| - |
41 |
| -``` |
42 |
| --4 + 2 = -2 // too small! |
43 |
| -``` |
44 |
| - |
45 |
| -The result of `l + r` gave you a value that is smaller than the target number. Thus, you have two options: |
46 |
| - |
47 |
| -1. Increase the lower number. |
48 |
| -2. Increase the higher number. |
49 |
| - |
50 |
| -Because your array is sorted, you can quickly identify that you cannot pick option **2**, since the rightmost number is already the biggest number. Thus, you have no choice but to try for a different number from the left end of the array: |
51 |
| - |
52 |
| -``` |
53 |
| -[-4, -1, -1, 0, 1, 2] |
54 |
| - l r |
55 |
| -``` |
56 |
| - |
57 |
| -This time, you'll get the following result from summing `l` and `r`: |
58 |
| - |
59 |
| -``` |
60 |
| --1 + 2 = 1 // too big! |
61 |
| -``` |
62 |
| - |
63 |
| -This time, the value is too big! I hope you see where it goes from here. Since the array is already sorted, you can only decrease the value on the right side in an attempt to balance things out. Hence, the next iteration of your algorithm will look like this: |
| 18 | +2. Ignoring duplicate values |
64 | 19 |
|
65 |
| -``` |
66 |
| -[-4, -1, -1, 0, 1, 2] |
67 |
| - l r |
68 |
| -``` |
69 |
| - |
70 |
| -And then you've found a match :] |
71 |
| - |
72 |
| -``` |
73 |
| --1 + 1 = 0 |
74 |
| -``` |
75 |
| - |
76 |
| -# 3Sum |
77 |
| - |
78 |
| -Let's start from scratch and consider the same problem where you've sorted your input and you're target sum is **0**: |
79 |
| - |
80 |
| -``` |
81 |
| -[-4, -1, -1, 0, 1, 2] |
82 |
| - l r |
83 |
| -``` |
84 |
| - |
85 |
| -Your goal this time is the following equation: |
86 |
| - |
87 |
| -``` |
88 |
| -l + r + m = 0 |
89 |
| -``` |
90 |
| - |
91 |
| -You have the values of `l` and `r`: |
92 |
| - |
93 |
| -``` |
94 |
| --4 + 2 + m = 0 |
95 |
| -
|
96 |
| -// in other words |
97 |
| -m = 4 - 2 = 2 |
98 |
| -``` |
99 |
| - |
100 |
| -For the current values of `l` and `r`, you need to find a value of **2** in the array to satisfy your target sum... |
101 |
| - |
102 |
| -#### Finding `m` |
103 |
| - |
104 |
| -``` |
105 |
| - m -- where? |
106 |
| -[-4, -1, -1, 0, 1, 2] |
107 |
| - l r |
108 |
| -``` |
109 |
| - |
110 |
| -There are slight optimizations you can do to find `m`, but to keep things simple, you'll just iterate through the array from `l` index to the `r` index. Once you find a value where `l + r + m = target`, you've found your first match! |
| 20 | +3. Clever adjustment of indices for each pass. |
111 | 21 |
|
112 | 22 | #### Avoiding Duplicates
|
113 | 23 |
|
@@ -157,6 +67,8 @@ extension BidirectionalCollection where Element: Equatable {
|
157 | 67 | }
|
158 | 68 | ```
|
159 | 69 |
|
| 70 | +### |
| 71 | + |
160 | 72 | ## 4Sum
|
161 | 73 | Given an array S of n integers, find all subsets of the array with 4 values where the 4 values sum up to a target number.
|
162 | 74 |
|
|
0 commit comments