Skip to content

Commit d74997f

Browse files
committed
add 3 sum solution
1 parent 15b0841 commit d74997f

File tree

1 file changed

+90
-0
lines changed

1 file changed

+90
-0
lines changed

15 - 3 Sum.md

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# 15 - 3 Sum
2+
3+
Difficulty: medium
4+
Done: No
5+
Last edited: February 22, 2022 1:23 AM
6+
Topic: array, sorting, two pointers
7+
8+
## Problem
9+
10+
Given an integer array nums, return all the triplets `[nums[i], nums[j], nums[k]]` such that `i != j``i != k`, and `j != k`, and `nums[i] + nums[j] + nums[k] == 0`.
11+
12+
Notice that the solution set must not contain duplicate triplets.
13+
14+
## Solution
15+
16+
Problem is framed like the popular two sum where we find 2 values $(x, y)$ which add up to given target, which can be solved by finding if difference between target and value $(target - x)$ exists in array.
17+
18+
However, here we are required to work with 3 values $(x, y, z)$ and **find all triplets where sum of values is zero** $x+y+z=0$. This must be done without repeating the elements, though input array can contain duplicates.
19+
20+
This approach will only work with sorted array
21+
22+
### Pseudo
23+
24+
1. Sort array
25+
2. Iterate through elements, setting current element as the pivot $x$.
26+
1. if current value (lowest) is greater than zero, then this would indicate there are only non-negative elements, which cannot sum to 0.
27+
2. if current value is same as preceding (duplicate), then skip.
28+
3. Proceed to step 3
29+
3. Use two pointer approach to compare values, starting with *left_ptr* at position $x+1$, and *right_ptr* at the end of the array or $len(nums)$-1. We want to find all pairs whose sum is equal to 0, or $(x+y+z)=0$.
30+
31+
We will do so by creating separate function which essentially performs two-sum. Loop while *left_ptr* is smaller than *right_ptr*
32+
33+
1. If $sum(x, y, z)$ is greater than 0, we will increment *left_ptr*
34+
2. Elif $sum(x,y, z)$ is less than 0, we will decrement *right_pt*
35+
3. if sum is zero, meaning **triplet found,** add to results list. Increment left and decrement right. Increment left while while $left = left+1$, to skip duplicates.
36+
37+
## Whiteboard
38+
39+
[http://excalidraw.com](http://excalidraw.com)
40+
41+
## Code
42+
43+
```python
44+
class Solution:
45+
def threeSum(self, nums: List[int]) -> List[List[int]]:
46+
triplets = []
47+
nums.sort()
48+
49+
for i in range(len(nums)):
50+
# check if all elements are non-negative
51+
if nums[i] > 0:
52+
break
53+
54+
# skip duplicates
55+
# call two_sum function to find triplets with i as target
56+
if nums[i-1] != nums[i] or i == 0:
57+
self.two_sum(i, nums, triplets)
58+
59+
return triplets
60+
61+
62+
def two_sum(self, i: int, nums: List[int], triplets: List[List[int]]):
63+
# define left & right pointers
64+
# loop while left & right pointers aren't at same position l < r
65+
66+
left = i + 1
67+
right = len(nums) - 1
68+
69+
while left < right:
70+
total = nums[i] + nums[left] + nums[right]
71+
72+
73+
#if sum > 0, increment left
74+
if total < 0:
75+
left += 1
76+
77+
# if sum < 0, decrement right
78+
elif total > 0:
79+
right -= 1
80+
81+
else:
82+
# if sum is 0, add to triplets list
83+
triplets.append([nums[i], nums[left], nums[right]])
84+
left += 1
85+
right -= 1
86+
87+
while left < right and nums[left] == nums[left-1]:
88+
# skip duplicates
89+
left += 1
90+
```

0 commit comments

Comments
 (0)