Description
Given an array nums of n integers, are there elements a, b, c in nums such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.
Note:
The solution set must not contain duplicate triplets.
Example:
Given array nums = [-1, 0, 1, 2, -1, -4], A solution set is: [ [-1, 0, 1], [-1, -1, 2] ]
Submission 1 – Brute-force
The brute-force solution is O(N^3) and it will exceed the time limit. This is a failed attempt, I will try to optimize the submission tomorrow.
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> res = new ArrayList<List<Integer>>();
Arrays.sort(nums);
for(int i = 0; i < nums.length; i++) {
for(int j = i + 1; j < nums.length; j++) {
for(int k = j + 1; k < nums.length; k++) {
if(i == j || i == k || j == k) continue;
if(nums[i] + nums[j] + nums[k] == 0 &&
nums[i] <= nums[j] && nums[j] <= nums[k]) {
List<Integer> t = List.of(nums[i], nums[j], nums[k]);
if(!res.contains(t)) {
res.add(t);
}
}
}
}
}
return res;
}
}
Submission 2
It again fails.
class Solution:
def twoSum(self, s, nums) -> List[List[int]]:
res = []
for i in nums:
if nums[i] > 0:
nums[i] -= 1
if (s - i) in nums and nums[s - i] > 0:
res.append([i, s-i])
nums[i] += 1
return res
def threeSum(self, nums: List[int]) -> List[List[int]]:
res = []
d = dict()
for n in nums:
if n in d:
d[n] += 1
else:
d[n] = 1
for i in d:
d[i] -= 1
two = self.twoSum(-i, d)
if two and len(two):
for t in two:
t.append(i)
t.sort()
if t not in res:
res.append(t)
d[i] += 1
return res
Submission 3
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
res = []
nums.sort()
for i in range(len(nums) - 2):
if nums[i] > 0:
break
l = i + 1
r = len(nums) - 1
while(l < r):
s = nums[i] + nums[l] + nums[r]
if s == 0 and [nums[i], nums[l], nums[r]] not in res:
res.append([nums[i], nums[l], nums[r]])
elif s < 0:
l += 1
else:
r -= 1
return res
Submission 4 & Solution
My problem in the previous submissions is that I used the ‘in’ function, it should be slow on a list and exceeds the time limit.
Instead, since the array is sorted, we should only take the first number in a series of the same number. Comparison after putting the 3 numbers together can be expensive.
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
res = []
nums.sort()
length = len(nums)
for i in range(length - 2):
if nums[i] > 0:
break
if i > 0 and nums[i] == nums[i - 1]:
continue
l = i + 1
r = length - 1
while l < r:
s = nums[i] + nums[l] + nums[r]
if s == 0:
res.append([nums[i], nums[l], nums[r]])
while l < r and nums[l+1] == nums[l]:
l += 1
while l < r and nums[r-1] == nums[r]:
r -= 1
l += 1
r -= 1
elif s < 0:
l += 1
else:
r -= 1
return res
200708 Revisited(C++ Version)
Description

Submission
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
sort(nums.begin(), nums.end());
vector<vector<int>> res;
for(int i = 0; i < nums.size(); ++i) {
for(int j = i + 1, k = nums.size() - 1; j < k; ) {
if(nums[j] + nums[k] < -nums[i])j++;
else if(nums[j] + nums[k] > -nums[i])k--;
else if(nums[j] + nums[k] == -nums[i]) {
res.push_back({nums[i], nums[j], nums[k]});
while(j + 1 < nums.size() && nums[j+1] == nums[j]) j++;
while(j < k && nums[k-1] == nums[k])k--;
j++; k--;
}
}
while(i + 1 < nums.size() && nums[i+1] == nums[i]) i++;
}
return res;
}
};