LeetCode 15 sum of three numbers

Keywords: Algorithm data structure leetcode

LeetCode 15 sum of three numbers

Title Description

Give you an array num containing n integers. Judge whether there are three elements a, b and c in num, so that a + b + c = 0? Please find all triples with sum 0 and no repetition. OJ link

Train of thought analysis

  • First, special cases shall be handled

    • If the array is empty, an empty collection is returned directly
    • The array length is 0, and the empty collection is returned directly
    • If the length of the array is less than 3 (at least three numbers must be added), an empty set is returned directly
  • Then perform * * ascending * * sorting

  • Enter the loop as * * a * * of the three elements from the minimum num [i] (sorted in ascending order)

    • If a is greater than 0, exit the loop directly.

      As shown below, due to the ascending sorting, if the current element a is greater than 0, then the subsequent elements are also greater than 0, plus b and c must be greater than 0, there is no need to continue to look back.

    • If nums[i] == nums[i - 1], you need to skip this element and duplicate results will appear

      As shown below, when num [I-1] = - 1, there is already a result [- 1,0,1], but when num [i] = - 1, there will also be a result [- 1,0,1]. It is required in the title that the result cannot be repeated. Therefore, when it is judged that * * num [i] = = num [I - 1] * * needs to skip this element

    • Define the left and right pointers, and scan from the adjacent element nums[i+1] * * on the right of a and the last element nums[nums.length-1] of the array to the middle, which are nums[left] (b) and nums[right] respectively** ©

    • **Case 1: * * if num [i] + num [left] + num [right] = = 0, add it to the result set, and then move the left and right pointers.

      As shown below, [- 4,1,3] is a group of results. After finding it, move the left and right pointers (left + +, right --). After moving, we find that num [left] = = num [left-1], Num [right] = = num [right + 1]. In this case, a group of results of [- 4,1,3] will appear, which causes repetition, so we need to judge separately.

    • **Case 2: * * if num [i] + num [left] + num [right] < 0, you need to increase the overall value. However, if num [i] is fixed and num [right] is the current maximum element, you can only increase num [left], that is, move the left pointer to the right.

      As shown below, a + B + C = - 4-3 + 3 = - 4 < 0. Since the left 3 is already the largest, we can only move the left pointer so that it can find satisfactory elements all the time

    • **Case 3: * * if num [i] + num [left] + num [right] > 0, the overall value needs to be reduced, but num [i] is fixed and num [left] is the current minimum element, so only num [right] can be reduced, that is, the right pointer can be moved to the left.

      As shown below, a + B + C = - 1 + 0 + 3 = 2 > 0. Since the left 0 is the smallest, we can only move the right pointer to find the satisfying element

  • End the loop and return the result.

solve

public static List<List<Integer>> threeSum(int[] nums)
{
    //Create result array
    List<List<Integer>> lists = new ArrayList<>();
    //If the array is empty or the length of the array is less than 3, null is returned directly
    if (nums == null || nums.length < 3)
    {
        return lists;
    }
    //Ascending sort
    Arrays.sort(nums);
    //Fix one element in turn as a
    for (int i = 0; i < nums.length - 2; i++)
    {
        //Because it has been arranged in ascending order, if the fixed element is greater than 0, the subsequent element must not be 0, and the subsequent element is also larger than the current element
        if (nums[i] > 0)
        {
            return lists;
        }
        //Avoid repeating elements. If the previous element is equal to the current element, you need to skip the element
        if (i > 0 && nums[i] == nums[i - 1])
        {
            continue;
        }
        //Define left and right pointers to find both the next position of the fixed element and the last position of the array
        int left = i + 1;
        int right = nums.length - 1;
        while (left < right)
        {
            //If equal to, add to the result set
            if (nums[i] + nums[left] + nums[right] == 0)
            {
                ArrayList<Integer> list = new ArrayList<>();
                list.add(nums[i]);
                list.add(nums[left]);
                list.add(nums[right]);
                lists.add(list);
                left++;
                right--;
                //Skip repeating elements and find the next pair
                while (left < right && nums[left] == nums[left - 1])
                {
                    left++;
                }
                while (left < right && nums[right] == nums[right + 1])
                {
                    right--;
                }
            }
            //If the sum of the three is less than 0, the left pointer is moved to the right (the array elements increase from left to right, so the left shift value also increases)
            else if (nums[i] + nums[left] + nums[right] < 0)
            {
                left++;
            }
            //If the sum of the three is greater than 0, the right pointer is moved to the left (the array elements increase from left to right, so the right shift value decreases)
            else
            {
                right--;
            }
        }
    }
    return lists;
}

Posted by zander213 on Thu, 30 Sep 2021 12:18:43 -0700