Posted on

Description

Given an array nums of n integers, are there elements abc 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;
    }
};

Leave a Reply

Your email address will not be published. Required fields are marked *