LeetCode刷题笔记(4Sum)
这道题本来昨天就做完了,但由于昨天要主持支部组织生活会,所以才拖到了今天,下面来分享一下经验吧!
Given an array nums of n integers and an integer target, are there elements a, b, c, and d in nums such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target.
Note:
The solution set must not contain duplicate quadruplets.
Example:
Given array nums = [1, 0, -1, 0, -2, 2], and target = 0.
A solution set is:
[
[-1, 0, 0, 1],
[-2, -1, 1, 2],
[-2, 0, 0, 2]
]
题意分析:
给定一个包含n个整数的nums数组(数组没有特殊指明,应该可以为空集),请计算有多少组四元组合之和为target,找出所有的唯一组合。注:解的集合中不应包含重复的组合。
解答如下:
方法一(对撞“指针”法)
先对向量进行排序,然后用第一个for循环固定向量中最左边第一个数nums[0],嵌套第二个for循环固定nums[1],再将其余两个数的之和(target-nums[0]-nums[1])看成一个数(sum),紧接着用对撞“指针”的方式,从排除了固定数的向量的两端进行扫描,若遇到两指针所指元素之和为sum则分别存下这两个数。最后用两层for循环依次固定每两个元素,执行相同操作,直到倒数第三、四个数即可。
class Solution{
public:
vector<vector<int> > fourSum(vector<int> & nums, int target){
vector<vector<int> > result;
vector<int> cur(4);
sort(nums.begin(), nums.end());
int sum = 0;
int len = (int) nums.size();
if (len < 4)
return result;
for (int i = 0; i < len - 3; i++) {
cur[0] = nums[i];
for (int j = i + 1; j < len - 2; j++) {
cur[1] = nums[j];
sum = target - nums[i] - nums[j];
for (int l= j + 1, r = len - 1; l < r; ) {
if ( nums[l] + nums[r] == sum){
cur[2] = nums[l++];
cur[3] = nums[r--];
result.push_back(cur);
while(l < r && nums[l] == nums[l-1] ) l++; //为了避免出现重复解
while(l < r && nums[r] == nums[r+1]) r--; //为了避免出现重复解
}
else if( nums[l] + nums[r] < sum )
l++;
else
r--;
}
while(j < len - 2 && nums[j] == nums[j+1]) j++; //为了避免出现重复解
}
while(i < len - 3 && nums[i] == nums[i+1]) i++; //为了避免出现重复解
}
return result;
}
};
提交后的结果如下:
方法二(优化方法一)
①用continue来提前结束不必要的循环 。②对于二维向量的赋值,应先创建一个定长的一维向量,然后对一维向量用push_back方法进行挨个存储,最后二维向量用push_back方法把一维向量挨个存储下来。③当for循环的第三个表达式为空时,一般可以改写成while循环。④tmp.clear();用于清理缓存。
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int>> result;
int len = nums.size();
if (len < 4)
return result;
vector<int> tmp;
sort(nums.begin(),nums.end());
for (int i = 0; i < len-3; i ++)
{
if (i > 0 && nums[i] == nums[i-1])
continue;
for (int j = i+1; j < len-2; j ++)
{
if (j > i+1 && nums[j] == nums[j-1])
continue;
int l = j+1;
int r = len-1;
while (l < r)
{
if (nums[i]+nums[j]+nums[l]+nums[r] < target)
l++;
else if (nums[i]+nums[j]+nums[l]+nums[r] > target)
r--;
else
{
tmp.clear(); //清理缓存
tmp.push_back(nums[i]);
tmp.push_back(nums[j]);
tmp.push_back(nums[l]);
tmp.push_back(nums[r]);
result.push_back(tmp);
l++;
r--;
while (l < r && nums[l] == nums[l-1])
l++;
while (l < r && nums[r] == nums[r+1])
r--;
}
}
}
}
return result;
}
};
提交后的结果如下:
日积月累,与君共进,增增小结,未完待续。