Problem description
Give you an array of n integers, nums, and a target value, target. Please find and return the quads [nums[a], nums[b], nums[c], nums[d]]:
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.
Example 1:
Input: num = [1,0, - 1,0, - 2,2], target = 0
Output: [[- 2, - 1,1,2], [- 2,0,0,2], [- 1,0,0,1]]
Example 2:
Input: num = [2,2,2,2,2], target = 8
Output: [[2,2,2,2]]
- 1 <= nums.length <= 200
- -10^9 <= nums[i] <=
- 10^9
- -10^9 <= target <=
- 10^9
solution
The sum of three numbers is enough headache. I don't know how to optimize the sum of four numbers on this basis
Use a double loop to enumerate the first two numbers respectively, and then use a double pointer to enumerate the remaining two numbers after the number enumerated by the double loop. Suppose that the first two numbers enumerated by the double loop are located in the subscripts i and j respectively, where i < J. Initially, the left and right pointers point to subscript j+1 and subscript n − 1 respectively. Calculate the sum of four numbers each time, and perform the following operations:
If the sum is equal to target, add the four enumerated numbers to the answer, then move the left pointer to the right until different numbers are encountered, and move the right pointer to the left until different numbers are encountered;
If the sum is less than target, move the left pointer to the right one bit;
If the sum is greater than target, the right pointer is moved one bit to the left.
During specific implementation, you can also perform some pruning operations:
After determining the first number, if num [i] + num [i + 1] + num [i + 2] + num [i + 3] > target, it means that no matter what value is taken for the remaining three numbers, the sum of the four numbers must be greater than the target, so exit the first cycle;
After determining the first number, if num [i] + num [n − 3] + num [n − 2] + num [n − 1] < target, it means that no matter what value is taken for the remaining three numbers, the sum of the four numbers must be less than target. Therefore, the first cycle directly enters the next round to enumerate num [i + 1];
After determining the first two numbers, if num [i] + num [J] + num [J + 1] + num [J + 2] > target, it means that no matter what value is taken for the remaining two numbers, the sum of the four numbers must be greater than the target, so exit the second cycle;
After determining the first two numbers, if nums[i]+nums[j]+nums[n − 2]+nums[n − 1] < target, it means that no matter what value the remaining two numbers take, the sum of the four numbers must be less than the target. Therefore, the second cycle directly enters the next round to enumerate nums[j+1].
class Solution { public: vector<vector<int>> fourSum(vector<int>& nums, int target) { vector<vector<int>> quadruplets; // If the number is less than 4, an empty array is returned if (nums.size() < 4) { return quadruplets; } sort(nums.begin(), nums.end()); int length = nums.size(); for (int i = 0; i < length - 3; i++) { if (i > 0 && nums[i] == nums[i - 1]) { continue; } // A good solution to large sum and incalculability if (nums[i] + nums[i + 1] -target > -(nums[i + 2] + nums[i + 3])) { break; } if (nums[i] + nums[length - 3] -target < -(nums[length - 2] + nums[length - 1])) { continue; } for (int j = i + 1; j < length - 2; j++) { if (j > i + 1 && nums[j] == nums[j - 1]) { continue; } if (nums[i] + nums[j] -target > -(nums[j + 1] + nums[j + 2]) ) { break; } if (nums[i] + nums[j] -target < -( nums[length - 2] + nums[length - 1])) { continue; } int left = j + 1, right = length - 1; while (left < right) { int sum = nums[i] + nums[j] + nums[left] + nums[right]; if (sum == target) { quadruplets.push_back({nums[i], nums[j], nums[left], nums[right]}); while (left < right && nums[left] == nums[left + 1]) { left++; } left++; while (left < right && nums[right] == nums[right - 1]) { right--; } right--; } else if (sum < target) { while (left < right && nums[left] == nums[left + 1]) { left++; } left++; } else { while (left < right && nums[right] == nums[right - 1]) { right--; } right--; } } } } return quadruplets; } };