首页 > 其他 > 详细

18. 4Sum

时间:2021-03-12 16:58:59      阅读:15      评论:0      收藏:0      [点我收藏+]

仅供自己学习

 

思路:

因为要去重,即[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 };

 

18. 4Sum

原文:https://www.cnblogs.com/Mrsdwang/p/14524368.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!