力扣 18 四数之和

18. 四数之和

给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):
  • 0 <= a, b, c, d < n
  • abc 和 d 互不相同
  • nums[a] + nums[b] + nums[c] + nums[d] == target

你可以按 任意顺序 返回答案 。

 

示例 1:

输入:nums = [1,0,-1,0,-2,2], target = 0
输出:[[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]]

示例 2:

输入:nums = [2,2,2,2,2], target = 8
输出:[[2,2,2,2]]

 

提示:

  • 1 <= nums.length <= 200
  • -109 <= nums[i] <= 109
  • -109 <= target <= 109

先理解最接近的三数之和(尤其是后面的大神解法)

一、排序

将nums排序

二、a,b去重

1 for(int i=0;i<len;i++){   
2             if(i==0||nums[i]!=nums[i-1])
3             for(int j=i+1;j<len;j++){
4                 if(j==i+1||nums[j]!=nums[j-1]){

三、循环和双指针

先用i和j 循环a和b的下标,接下来那么l和r就是c,d的,刚开始l在最左边,r在最右边,判断当前值tmp,

tmp>target,说明当前和过大了,应该让tmp减小,所以r左移,r--

tmp<target,说明当前和过小了,应该让tmp增大,所以l右移,l++

tmp==target,记录当前abcd,l++同时r--

四、c,d去重

 

 1 if(tmp==target){
 2                          
 3                             res.push_back({nums[i],nums[j],nums[l],nums[r]});
 4                                           
 5                             if((nums[r]==nums[r-1])||(nums[l]==nums[l+1])){
 6                                 while(r>l&&(nums[r]==nums[r-1]))
 7                                     r--;
 8                                 while(r>l&&(nums[l]==nums[l+1]))
 9                                     l++;
10                             }
11                             else
12                                 r--;l++;
13                            
14                                                          
15                         }

五、代码

 1 class Solution {
 2 public:
 3     vector<vector<int>> fourSum(vector<int>& nums, int target) {
 4         vector<vector<int>> res;
 5         sort(nums.begin(),nums.end());
 6         int len=nums.size();
 7         for(int i=0;i<len;i++){   
 8             if(i==0||nums[i]!=nums[i-1])
 9             for(int j=i+1;j<len;j++){
10                 if(j==i+1||nums[j]!=nums[j-1]){
11                     /*i和j就是a 和b的下标,那么l和r就是c,d的*/
12                    int r=len-1;
13                    int l=j+1;  
14                     while(l<r&&r>j){
15                         double  tmp=((double)nums[i]+nums[j]+nums[l]+nums[r]);//测试数据会有四个10^9相加,需要先强转double
16                         if(tmp>target){
17                             r--;
18                             continue;
19                         }
20                         if(tmp<target){
21                             l++;
22                             continue;
23                         }
24                         if(tmp==target){
25                          
26                             res.push_back({nums[i],nums[j],nums[l],nums[r]});
27                                           
28                             if((nums[r]==nums[r-1])||(nums[l]==nums[l+1])){
29                                 while(r>l&&(nums[r]==nums[r-1]))
30                                     r--;
31                                 while(r>l&&(nums[l]==nums[l+1]))
32                                     l++;
33                             }
34                             else
35                                 r--;l++;
36                            
37                                                          
38                         }
39                        
40                         
41                     }
42                 }
43             }
44         }
45         return res;
46     }
47 };

 

 

posted @ 2022-01-20 17:36  付玬熙  阅读(60)  评论(0编辑  收藏  举报