[Algorithm Beaten Diary] day04——15. The sum of three numbers, 18. The sum of four numbers

 

 15. Sum of three numbers

15. The sum of three numbers icon-default.png?t=N7T8https://leetcode.cn/problems/3sum/

Topic description:

Given an integer array  nums , determine whether there is a triple  [nums[i], nums[j], nums[k]] that satisfies  i != j, i != k and  j != k , and also satisfies  nums[i] + nums[j] + nums[k] == 0 . Please return all  0 triples whose sum is and are not repeated.

Note: Answers cannot contain duplicate triples.

Problem-solving ideas:

Let’s take a look at the question first: the question requires a+b+c=0, and the subscripts of the three numbers a, b, and c are different, and all possibilities are returned, and it is necessary to repeat

 We can first determine the general idea: sort sorting (ordered), ordering can be used by double pointers or bisection, here we use sort + double pointers

What we have here is the sum of three numbers. We can determine a cur subscript to traverse the array, one number at a time, and then the problem becomes the sum of the two numbers in the remaining array!

When we add two numbers, we can use double pointers to reduce time complexity. Left and right go from both sides to the middle.

What we are more concerned about here is the boundary between left and right. It is very easy to cross the boundary here! ! !

Let’s understand it by combining some of the code of this question

Our entire red area can be divided into [begin, right] (left and right are not used here to avoid confusion. Begin here represents the first red area, and end is the next one after the last red area). Normally we say left< end, right>0, but our subscript access here involves left+1 and right-1, so left needs to be one less than end, that is, let left+1 reach the maximum position of end-1. Similarly, right> 1

Solution code:

class Solution {
public:
       vector<vector<int>> threeSum(vector<int>& nums) {
        sort(nums.begin(), nums.end());
        vector<vector<int>> nnums;
        int size = nums.size();
        int cur = 0;
        while (cur < size - 1)
        {
            int left = cur + 1;
            int right = size - 1;
            int a = (-1) * nums[cur];//找到两数之和为a的两个值
            while (left < right)
            {
                if (nums[left] + nums[right] == a)
                {
                    nnums.push_back({ nums[cur],nums[left],nums[right] });
                    while (right > 1 && nums[right] == nums[right - 1])
                        right--;
                    right--;
                }
                else if (nums[left] + nums[right] > a)
                {
                    while (right > 1 && nums[right] == nums[right - 1])
                        right--;
                    right--;
                }
                else if (nums[left] + nums[right] < a)
                {
                    while (left<size-1&&nums[left] == nums[left + 1])
                        left++;
                    left++;
                }
            }
            while (cur<size-1&&nums[cur] == nums[cur + 1])
                cur++;
            cur++;

        }
        return nnums;
    }
};

18. Sum of four numbers

18. The sum of four numbers icon-default.png?t=N7T8https://leetcode.cn/problems/4sum/

 Topic description:

You are given an  n array of integers  nums and a target value  target . Please find and return a non- duplicate quadruple that  satisfies all the following conditions [nums[a], nums[b], nums[c], nums[d]] (if two quadruple elements correspond one-to-one, the two quadruples are considered to be duplicates):

  • 0 <= a, b, c, d < n
  • a, b, c and  d are different from each other
  • nums[a] + nums[b] + nums[c] + nums[d] == target

You can return answers in  any order  .

Problem-solving ideas:

This question is the same as the previous question. It is to add another layer on the basis of the sum of three numbers.

Solution code:

class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        sort(nums.begin(), nums.end());
        int size = nums.size();
        vector<vector<int>>nnums;
        for (int i = 0; i < nums.size();)
        {
            int cur = i+1;
            while (cur < size - 1)
            {
                int left = cur + 1;
                int right = size - 1;
                long long a = (long long)target-nums[i] - nums[cur];//找到两数之和为a的两个值
                while (left < right)
                {
                    if (nums[left] + nums[right] == a)
                    {
                        nnums.push_back({ nums[i],nums[cur],nums[left],nums[right] });
                        while (right > 1 && nums[right] == nums[right - 1])
                            right--;
                        right--;
                    }
                    else if (nums[left] + nums[right] > a)
                    {
                        while (right > 1 && nums[right] == nums[right - 1])
                            right--;
                        right--;
                    }
                    else if (nums[left] + nums[right] < a)
                    {
                        while (left < size - 1 && nums[left] == nums[left + 1])
                            left++;
                        left++;
                    }
                }
                while (cur < size - 1 && nums[cur] == nums[cur + 1])
                    cur++;
                cur++;
            }

            while (i < size - 1 && nums[i] == nums[i + 1])
                i++;
            i++;
        }
        return nnums;
    }
};

 

Guess you like

Origin blog.csdn.net/m0_69061857/article/details/132816282