LeetCode-15, 16: 3Sum & 3Sum Closest (the sum of three numbers)

Subject: 3 Sum

Given an array nums of n integers, are there elements a, b, c 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]
]

Problem analysis:

Given an array, return the triples that sum to 0 in the array.

Link:

ideas label

Algorithm: Double Pointer

answer:

  • Taking the idea of ​​LeetCode-1: Two Sum, because a+b+c=0, then a+b=-c;
  • The difference is that we need to return the element itself, so there is no need to use the associative container map;
  • At the same time, there are many different triples in the array that satisfy the condition;
  • In addition, because there are duplicate elements in the array, it is possible to get triples with the same elements and the same elements, but only one of them can be added;
  • So in order to avoid the duplication problem, we first sort the array and use the negative value of each element as the target to find the other two elements;
  • When looking for the other two elements, we use two pointers to point to the next position of the target element and the end of the array respectively, and search by comparing the size of the two numbers and the target value;
  • It is necessary to skip the following repeated elements after each time a set of triples is found; at the same time, the skip processing is also performed after each target value target is completed.
class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int> > ret;

        sort(nums.begin(), nums.end());
        for(int i=0; i<nums.size(); ++i){
            int low = i+1;
            int high = nums.size()-1;
            int target = -nums[i];

            while(low < high){
                int sum = nums[low] + nums[high];

                if(sum < target)
                    low++;
                else if(sum > target)
                    high--;
                else{
                    vector<int> triplets(3,0);
                    triplets[0] = nums[i];
                    triplets[1] = nums[low];
                    triplets[2] = nums[high];
                    ret.push_back(triplets);

                    while(low < high && nums[low] == triplets[1]) low++;
                    while(low < high && nums[high] == triplets[2]) high--;
                }
            }

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

Topic: 3 Sum Closest

Given an array nums of n integers and an integer target, find three integers in nums such that the sum is closest to target. Return the sum of the three integers. You may assume that each input would have exactly one solution.

example:

Given array nums = [-1, 2, 1, -4], and target = 1.

The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).

Problem analysis:

Given an array and a target value, returns the triplet in the array that sums closest to the target value.

Link:

ideas label

Algorithm: Double Pointer

answer:

  • With the idea of ​​LeetCode-15:3 Sum, we still traverse a candidate in the triplet first, and then select the remaining two elements in the form of double pointers;
  • Because we need to find the sum of the closest target value, we calculate each current triple, and through the absolute value comparison, record the sum of the current minimum absolute value and the closest target value each time;
  • Two values ​​are selected by comparing the difference.
class Solution {
public:
    int threeSumClosest(vector<int>& nums, int target) {  
        sort(nums.begin(), nums.end());

        int closestSum = nums[0] + nums[1] + nums[2];
        int minAbs = abs(closestSum - target);
        for(int i=0; i<nums.size(); ++i){
            int first = nums[i];
            int index2 = i+1;
            int index3 = nums.size()-1;
            while(index2 < index3){
                int tempSum = first + nums[index2] + nums[index3];
                int diff = tempSum - target;
                if(abs(diff) < minAbs){
                    minAbs = abs(diff);
                    closestSum = tempSum;
                }
                if(diff < 0) 
                    index2++;
                else if(diff > 0) 
                    index3--;
                else
                    return closestSum;
            } 
        }
        return closestSum;
    }
};

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324885195&siteId=291194637