Three sum algorithm solution

后端 未结 4 1050
迷失自我
迷失自我 2020-12-16 23:53

Original Problem Statement:

Given an array S of n integers, are there elements a, b, C in S such that a + b + c = 0? Find all unique triplets in the array which gives

相关标签:
4条回答
  • 2020-12-17 00:27

    One of the approach is using the HashSet, What I have try here:

    public List<List<Integer>> threeSum(int[] nums) {
            Set<List<Integer>> set = new HashSet<>();
            Arrays.sort(nums);
            for (int i = 0; i < nums.length - 1; i++) {
                int j = i + 1;
                int k = nums.length - 1;
                while (j < k) {
                    int sum = nums[i] + nums[j] + nums[k];
                    if (sum == 0) {
                        set.add(Arrays.asList(nums[i], nums[j++], nums[k--]));
                    } else if (sum > 0) {
                        k--;
                    } else if (sum < 0) {
                        j++;
                    }
                }
            }
            return new ArrayList<>(set);
        }
    }
    
    0 讨论(0)
  • 2020-12-17 00:27

    I'd like to add the answer you claimed(in the comment) to post:

    class Solution(object):
        def threeSum(self, nums):
            """
            :type nums: List[int]
            :rtype: List[List[int]]
            """
            def twoSum(self, nums, target):
                targ = target
                for index, i in enumerate(nums):
                    targ -= i
    
                    # if targ in nums[index+1:]:
                    #    return [nums[index], nums[nums[index+1:].index(targ)+index+1]]
                    _num = nums[:index] + nums[index+1:]
                    if targ in _num: 
                        return [i, targ]
                    else:
                        targ = target
                return None
            res = []
            for index, i in enumerate(nums):
                target = i * -1
                num = nums[:index] + nums [index+1:]
                ans = twoSum(self, num, target)
                if ans != None:
                    temp = ans + [i]
                    temp.sort()
                    res.append(temp)
            print(res)
            import itertools
            res.sort()
            res = list(res for res,_ in itertools.groupby(res))
            return res
    

    I have only run it my brain and hope it is right.

    0 讨论(0)
  • 2020-12-17 00:34

    using itertools.

    import itertools
    stuff = [-1, 0, 1, 2, -1, -4]
    stuff.sort()
    ls = []
    for subset in itertools.combinations(stuff, 3):
        if sum(list(subset))==0:
            # first I have sorted the list because of grouping
            # Ex: [-1, 0, 1] and [0, 1, -1] are build with the same element
            # so here is avoiding this.
            if list(subset) not in ls:
                ls.append(list(subset))
    print(ls)
    

    input/output

    input : [-1, 0, 1, 2, -1, -4]
    output : [[-1, -1, 2], [-1, 0, 1]]
    input : [-4,-2,-2,-2,0,1,2,2,2,3,3,4,4,6,6] 
    output: [[-4, -2, 6], [-4, 0, 4], [-4, 1, 3], [-4, 2, 2], [-2, -2, 4], [-2, 0, 2]]
    
    0 讨论(0)
  • 2020-12-17 00:41

    Here's another way of solving it which has O(n^2) time complexity and passes the LeetCode test. It counts the occurrences and then sorts (number, count) tuples so [-1, 0, 1, 2, -1, -4] becomes [(-4, 1), (-1, 2), (0, 1), (1, 1), (2, 1)]. Then it iterates from beginning picking first trying to pick each number twice and third greater if possible and add this to result. Then it picks number once and tries to find two greater numbers which sum to 0.

    from collections import Counter
    
    class Solution(object):
        def threeSum(self, nums):
            res = []
            counts = Counter(nums)
            num_counts = sorted(counts.items())
    
            # Handle the only case where we pick three same nums
            if counts[0] >= 3:
                res.append([0] * 3)
    
            for i, (first, first_count) in enumerate(num_counts):
                # Pick two of these and one greater
                if first_count >= 2 and first < 0 and -(first * 2) in counts:
                    res.append([first, first, -(first * 2)])
    
                # Pick one and two greater
                for j in range(i + 1, len(num_counts)):
                    second, second_count = num_counts[j]
                    # Pick two of these as second and third num
                    if second_count >= 2 and -first == 2 * second:
                        res.append([first, second, second])
    
                    # Pick this as second num and third which is greater
                    third = -(first + second)
                    if third > second and third in counts:
                        res.append([first, second, third])
    
            return res
    
    0 讨论(0)
提交回复
热议问题