集合重复问题
刷题时经常会遇到这种场景:类似于求n个数和为target,不止一种组合,结果返回{[...],[...],...}多个不重复数组的集合
此时需注意 [0,1,-1]和[1,0,-1]元素顺序不同,但所用元素相同,所以数组是重复的。
去重
1.排序。保证每一个数组是有顺序的,例如每一个数组中后一个元素比前一个元素大/小,这样可以去掉仅改变元素顺序而重复的数组,例如[0,1,-1]和[1,0,-1]。
排序有两种方式
(1)在挑选元素前(遍历前)就将数据排好序,再进行挑选,这样不用在循环内部加条件筛选。
vector<vector<int>> isRight(vector<int> nums,int target)
{
vector<vector<int>> result;//数组集合
vector<int> s; //两数之和=target的数组
//先排序
sort(nums.begin(),nums.end());
for(int i=0;i<nums.size()-1;i++){
for(int j=i+1;j<nums.size();j++){
if(nums[i]+nums[j]==target){
添加满足条件的元素
}
}
}
return result;
}
注意,这是在题目对元素顺序无要求的条件下,才可以这样做。例如题目不要求返回元素对应的下标(不要求返回元素在数组的位置),不要求保持元素原来在数组中的顺序。
(2)在遍历时添加条件筛选。
for(int i=0;i<nums.size()-1;i++)
for(int j=i+1;j<nums.size();j++)
//添加筛选条件
if(nums[i]+nums[j]==target&&nums[j]>=nums[i])
添加满足条件的元素
2.跳过重复元素。如果题目给的数组排好序后一重复的元素,例如[-1,0,1,1,1,2,5]。此时若target=0,要求三个数一组,那么即使排序了,也会有重复的组合,例如[-1,0,1]这种组合就会有三个。有三个1,遍历时,下标虽然在往后移,但值是一样的,都符合要求。其实,对于重复的元素,我们只需要取过一个即可,后面重复的元素,情况也是相同的,只需要跳过就好。
for(int i=0;i<nums.size()-1;i++)
if(i>0&&nums[i]==nums[i-1])
continue; //至少遍历了两个数,且第二个数与前一个数是重复的,则跳过该数
for(int j=i+1;j<nums.size();j++)
if(j>i+1&&nums[j]==nums[j-1])
continue; //j>i+1至少遍历了两个数,且第二个数与前一个数是重复的,则跳过该数
//添加筛选条件
if(nums[i]+nums[j]==target&&nums[j]>=nums[i])
添加满足条件的元素