题意:这是继2sum和3sum之后的4sum,同理,也是找到所有4个元素序列,满足他们之和为target。以vector<vector<int>>来返回,也就是二维的,列长为4,有多少个序列就多少行,每行都是唯一的,且升序。

思路:

方法一:用类似3sum的方法,先确定下第1个元素,再确定第2个元素,剩下两个元素用“两个指针”。前提是已排序。这个方法主要是怎么去重,这里提供两种方法:

1)用unordered_set,只要找到一个序列就检查里面有没有这样的序列,若没有就插入,这样保证了唯一性,最后再用迭代器遍历一次,逐个搬到vector中返回。

2)这是我用的方法。假设有序列 a{-2,-2,-2,-1,-1,0,0,1,1,2,2  }共11个元素,target=0。

  第1个元素取a[0],第2个元素取a[1],那么>1的所有两个数的组合会被“两个指针”所全部找到,而如果有重复的,都会是连续的重复,所以只要判断与上一个序列之中有一个值不同,就可以进行插入。(“两个指针”处的去重)

  接下来第2个元素会取a[2],但是a[1]=a[2],还有必要再试吗?不必要,看{-2,-2,a,b}=target,这里a和b已经将所有可能给试了,如果这此仍取a[2],那么仍然在试集合{-2,-2,a,b}中的a和b的值而已。这下如果重复了,就不一定会连续的重复了(可以自己列出),去重就麻烦了。所以第2个元素必须跳过已经扫过的值,也就是无论还有几个-2,直接跳过到-1。(第2个元素处的去重)

  第1个元素要取a[1]开始试吗?不用!道理同第2个元素的去重一样。所有以第1个元素为-2的序列已经都试出来了,再取-2也只是再找重复的序列,而且不是连续的。

 1 class Solution {
 2 public:
 3     vector<vector<int> > fourSum(vector<int> &num, int target) {
 4         sort(num.begin(), num.end());    //排序
 5         vector<int> group(4,10086);
 6         vector< vector<int> > ans;
 7         int n=num.size(), sum, sum2, *pl, *pr, old1=10086,old2=-10086 ;//这里的old可以随便取值,特殊一点的都行
 8         for(int j=0; j<n-3; j++ )    //第1个元素
 9         {
10             if(old1==num[j]) continue; else old1=num[j];
11             for(int i=j+1; i<n-2; i++ )//第2个元素
12             {
13                 if(old2==num[i])    continue; else old2=num[i];
14                 sum2 = target-num[i]-num[j] ;//寻找余下两数之和
15                 pl = &num[i+1];//左指针
16                 pr = &num[n-1];//右指针
17                 while(pl!=pr)
18                 {
19                     sum = *pl + *pr;
20                     if( sum == sum2 )
21                     {
22                         if( group[0]!=num[j] || group[1]!=num[i] || group[2]!=*pl || group[3]!=*pr )//只要有一个不同,便可添加
23                         {
24                             group[0] = num[j];
25                             group[1] = num[i];
26                             group[2] = *pl;
27                             group[3] = *pr;
28                             ans.push_back(group);
29                         }
30                         pl++;
31                     }
32                     else if( sum > sum2 )    pr--;
33                     else    pl++;
34                 }
35             }
36             old2=10086;
37         }
38         return ans;
39     }
40 };

4Sum

  

方法二:将序列中两两的和作为新的序列,那问题就转化为“求两个值的和”,也就是用“两个指针”法。这里的难点在于,找到和为target的新序列中的两个元素,如何找到他们原来的面目(4个元素)。还有个问题,元素会被你重复的利用。

比如,有序列a{-1,-1,0,1,1},

转成新序列{-2,-1,0,0,-1,0,0,1,1,2},

新序列是这么来的{-1+-1,-1+0,-1+1,-1+1,-1+0,-1+1,-1+1,0+1,0+1,1+1},

也就是{a[0]+a[1],a[0]+a[2], a[0]+a[3],a[0]+a[4] ,a[1]+a[2],a[1]+a[3],a[1]+a[4],a[2]+a[3],a[2]+a[4],a[3]+a[4]}。

假如target=0,我们在新序列中找到 -1+1=0,但是他们是a[0]+a[2]+a[2]+a[4]。也就是说,a[2]被算了两次了,是不允许的。

此方法还未实现,有空再想。

转载于:https://www.cnblogs.com/xcw0754/p/4396994.html

LeetCode 4Sum 4个数之和相关推荐

  1. [LeetCode] 4Sum II 四数之和之二

    Given four lists A, B, C, D of integer values, compute how many tuples (i, j, k, l) there are such t ...

  2. 18 4Sum(寻找四个数之和为指定数的集合Medium)

    题目意思:给一个乱序数组,在里面寻找三个数之和为target的所有情况,这些情况不能重复,增序排列 思路:采用3Sum的做法 ps:有见一种用hash的,存任意两个元素的和,然后变成3sum问题,需要 ...

  3. 数组-leetcode#15-找出三个数之和等于0的所有不重复序列

    class Solution { public:vector<vector<int>> threeSum(vector<int>& nums) {vecto ...

  4. [leetcode]1.两数之和

    [leetcode]1.两数之和 题目 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 的那 两个 整数,并返回它们的数组下标. 你可以假设每种输入只会对应 ...

  5. [双指针|模拟] leetcode 15 三数之和

    [双指针|模拟] leetcode 15 三数之和 1.题目 题目链接 给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ? ...

  6. [hashmap|空间换时间] leetcode 1 两数之和

    [hashmap|空间换时间] leetcode 1 两数之和 1.题目 题目链接 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下 ...

  7. 20200126:(leetcode)三数之和 最接近的三数之和(含图解)

    三数之和 && 最接近的三数之和 题目 基本思路 代码实现 题目 三数之和 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b ...

  8. C/C++描述 LeetCode 167. 两数之和 II - 输入有序数组

    C/C++描述 LeetCode 167. 两数之和 II - 输入有序数组   大家好,我叫亓官劼(qí guān jié ),在CSDN中记录学习的点滴历程,时光荏苒,未来可期,加油~博主目前仅在 ...

  9. LeetCode 1. 两数之和

    LeetCode 1. 两数之和 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标. 你可以假设每种输入 ...

最新文章

  1. sqlserver2008 R2中查找未使用过的索引
  2. 记一次php项目上线遇到的坑
  3. Python---多任务介绍以及Thread的基本使用
  4. PyTorch的六个学习率调整
  5. java在己有的类创子类怎么创_使用Java创建自己的异常子类
  6. 正则表达式格式化字符串
  7. 用C/C++实现倒序输出,以12345为例
  8. ICPC Trainings Moscow2020 K. King and Zeroing 树直径 + 思维
  9. [引]生成加密和解密的密钥
  10. 图书馆管理系统项目思路
  11. 计算机顶会论文写作科研利器
  12. 全局变量定义的时候左侧加了static_c语言中static 用法
  13. 解决python ConfigParser文件编码问题(按指定格式存储文件(txt))
  14. 游戏筑基开发之二进制文件操作的那点事儿(C语言)
  15. CAD绘图设计效率慢?这些外挂神器帮你1小时完成3小时的工作!
  16. 硬件的驱动和sdk的理解与应用
  17. win7电脑误删鼠标键盘驱动_鼠标键盘,教您怎么解决键盘和鼠标失灵的问题
  18. 高项 人力资源管理论文
  19. python绘制包络线_包络线和包络谱计算程序
  20. 加强化工企业危化品管理的几点建议

热门文章

  1. 现代计算机网络发展为第几代,晶体管计算机是第几代_个人计算机使用的电子元器件_计算机网络最突出的(6)...
  2. 使用计算机报点系统时填记,子案例库接发列车工作-企业生产实际教学案例库...
  3. 前端知识天天学(2)
  4. Qt之tcp的简单使用
  5. vmware虚拟机中常见的3种网络模式
  6. 送17届学弟学妹的礼物——学生包、学生优惠合集
  7. JAVA学习(三):Java基础语法(变量、常量、数据类型、运算符与数据类型转换)...
  8. Centos Nginx+PHP Install 史上最完美
  9. 开发安全的ASP.NET应用程序
  10. 寻找 时间轴网页设计灵魂