The leecode algorithm "Sum of 15.3 Numbers" is annotated and simple.

Posted by kool_samule on Sat, 17 Aug 2019 09:31:46 +0200

The leecode algorithm "Sum of 15.3 Numbers" is annotated and simple.

Content of the original topic

Given a n array nums containing n integers, determine whether there are three elements a, b, c in nums, so that a + b + c = 0? Find out all triples that satisfy the conditions and do not repeat.

Note: The answer should not contain duplicate triples.

For example, given array nums = [-1, 0, 1, 2, -1, -4],

The set of triples satisfying the requirements is:
[
[-1, 0, 1],
[-1, -1, 2]
]

Source: LeetCode
Link: https://leetcode-cn.com/problems/3sum
Copyright belongs to the seizure network. For commercial reprints, please contact the official authorization. For non-commercial reprints, please indicate the source.

Solution 1:

This solution is not recommended, but the blogger has worked hard to write it out and needs to talk about it.
The idea is to convert the sum of three numbers into the sum of two numbers.
a+b+c=0 ==>a+b=-c
According to the above formula, the sum of three numbers becomes the sum of two numbers.
Need to loop the array, take out each value as - c, and then find two numbers in the original array equal to - C after OK;
The difficulty of this method is to de-duplicate the result set.
I wrote the code, but the execution timeout on leecode is not recommended.

Code

      public static List<List<Integer>> threeSum(int[] nums) {
        if (nums.length < 3) {
            return new ArrayList<>();
        }
        List<List<Integer>> result = new ArrayList<>();
        for (int i = 0; i < nums.length; i++) {
            List<List<Integer>> c = threeTwo(nums, -nums[i], i);
            for (int t = 0; t < c.size(); t++) {
                boolean add = true;
                for (int y = 0; y < result.size(); y++) {
                    List<Integer> integers = c.get(t);
                    List<Integer> c1 = result.get(y);
                    if (integers.get(0).equals(c1.get(0)) && integers.get(1).equals(c1.get(1)) && integers.get(2).equals(c1.get(2))) {
                        add = false;
                    }

                }
                if (add) {
                    result.add(c.get(t));
                }
            }
        }
        return result;
    }

    public static List<List<Integer>> threeTwo(int[] nums, int target, int j) {
        List<List<Integer>> result = new ArrayList<>();
        Map<Integer, Integer> map = new HashMap<>(16);
        for (int i = 0; i < nums.length; i++) {
            List<Integer> list = new ArrayList<>();
            if (map.get(nums[i]) != null && i != j) {
                list.add(nums[i]);
                list.add(map.get(nums[i]));
                list.add(-target);
                Collections.sort(list);
                result.add(list);
            } else {
                if (i != j) {
                    map.put(target - nums[i], nums[i]);
                }
            }
        }
        return result;
    }

Solution 2

I'm dumb anyway. I didn't think of the double pointer method.
The method of double pointer is really handsome.
Ideas:

Illustration:

The code is annotated and the logic is clear.

   public static List<List<Integer>> threeSum4(int[] nums) {
        // Sort the numbers first
        Arrays.sort(nums);
        // Create a collection to store the result set
        List<List<Integer>> result = new ArrayList<>();
        // Find the length of the array
        int length = nums.length;
        for (int k = 0; k < length - 2; k++) {
            // If the number of cycles needed is 0, then there must not be three numbers added up equal to 0, jumping out of the cycle directly.
            if (nums[k] > 0)break;
            // If the number of cycles repeats the number of previous cycles, skip directly to prevent duplicate values from occurring in the result set.
            if (k > 0 && nums[k] == nums[k - 1])continue;
            // Define two pointers. i points to the last number of K, and j points to the last number of the array.
            int i = k + 1;
            int j = length - 1;
            while (i < j) {
                // Find the sum of three numbers
                int sum = nums[k] + nums[i] + nums[j];
                if (sum < 0) {
                    // If the result of "0, i++; the following code does not understand, you need to look at the difference between + + I and i++.
                    while (i < j && nums[i] == nums[++i]) ;
                } else if (sum > 0) {
                    // If the result is > 0, j--;
                    while (i < j && nums[j] == nums[--j]) ;
                } else {
                    // If the result = 0, the result is stored in the set; and I++;J--
                    result.add(new ArrayList<>(Arrays.asList(nums[k], nums[i], nums[j])));
                    while (i < j && nums[i] == nums[++i]) ;
                    while (i < j && nums[j] == nums[--j]) ;
                }
            }
        }
        return result;
    }

Topics: network