仅供自己学习
思路:
因为要去重,即[0,-1,1,0]和[1,-1,0,0]不能同时存在,而nums又是随机的排序的数组,所以可能会在遍历的时候加入了重复的结果组合。
为了去重和减少时间消耗,我们可以先对nums进行排序,并用4个指针进行移动控制,首先两个指针,固定a,b在左边,然后c=b+1,d=size-1,通过移动c,d来遍历。保存使得nums[a]+nums[b]+nums[c]+nums[d]==target的解。偏大时d左移,偏小时c右移。c和d相遇时,表示以当前的a和b为最小值的解已经全部求得。b++,进入下一轮循环b循环,当b循环结束后。a++,进入下一轮a循环。 即(a在最外层循环,里面嵌套b循环,再嵌套双指针c,d包夹求解)。
去重的判断就是每次abcd增长时候都判断是否等于上次经历过的位置得元素,如果等于就continue再次移动重复的指针,直到定位在新的元素,由此可以去重。这样做正确是因为我们排了序,且相同的元素相加得到target的组合遍历过那么就一定会重复,所以直接去过重复元素
代码:
1 class Solution { 2 public: 3 vector<vector<int>> fourSum(vector<int>& nums, int target) { 4 sort(nums.begin(),nums.end()); 5 vector<vector<int>> res; 6 if(nums.size()<4) return res; 7 int size=nums.size(); 8 for(int a=0;a<=size-4;++a){ 9 if(a>0&&nums[a]==nums[a-1]) continue;//保证a指针能不指向重复的元素,如果重复就会持续移动a,直到走出重复 10 for(int b=a+1;b<=size-3;++b){ 11 if(b>a+1&&nums[b]==nums[b-1]) continue; 12 int c=b+1; 13 int d=size-1; 14 while(c<d){ 15 if(nums[a]+nums[b]+nums[c]+nums[d]<target) c++; 16 else if(nums[a]+nums[b]+nums[c]+nums[d]>target) d--; 17 else{ 18 res.push_back({nums[a],nums[b],nums[c],nums[d]}); 19 while(c<d&&nums[c]==nums[c+1]) //如果一直有重复的元素,最后还是会停到最后一个重复元素,然后下面在c++就可以走出重复了 20 c++; 21 while(c<d&&nums[d-1]==nums[d]) 22 d--; 23 c++; 24 d--; 25 26 } 27 } 28 29 } 30 } 31 return res; 32 33 } 34 };
原文:https://www.cnblogs.com/Mrsdwang/p/14524368.html