一.题目

3Sum

Total Accepted: 45112 Total
Submissions: 267165My
Submissions

Given an array S of n integers, are there elements abc in S such that a + b + c =
0? Find all unique triplets in the array which gives the sum of zero.

Note:

  • Elements in a triplet (a,b,c) must be in non-descending order. (ie, a ≤ b ≤ c)
  • The solution set must not contain duplicate triplets.
  1. For example, given array S = {-1 0 1 2 -1 -4},
  2.  
  3. A solution set is:
  4. (-1, 0, 1)
  5. (-1, -1, 2)
Show Tags
Have you met this question in a real interview?

Yes
No

Discuss
























二.解题技巧

    这道题和另外一道题Two Sum非常类似,只是这道题是在数组中寻找三个数,使得其和为0,同一时候要求这三个数仅仅能出现一次。假设单纯得使用暴力算法来做的话。时间复杂度为O(n^3)。且非常难推断这一组数是否已经出现过。
    假设考虑将数组A(元素个数为n)进行升序排序。那么依照顺序将数组中的第i个数作为三个数中最小的数。寻找从A的第i+1个数到n-1个数中满足和为-A[i]的数。就能够找到满足三个数和为0的组合了,可是,单独考虑这样的情况,会出现反复的问题。

要保证不出现反复的情况,当i!=0时,假设第i个数与第i-1个数同样的话,则不进行处理,直接处理第i+1个元素。这样。仅仅要保证三个数中最小的数是依照顺序递增的。那么算法找到的解就都是不反复的。

    这道题的边界条件在于:因为我们选择的是三个数中的最小值,因此。对于这个数的循环是[0, n-2)。同一时候,要对最小值进行消除反复的元素时。须要从第1个元素開始推断。假设从第0个元素開始推断的时候。可能会将0。0,0这样的情况忽略掉,因此,在消除反复的最小元素时,必须从第1个元素才開始。
    这道题在寻找数组A中的两个数的和为-A[i]时,能够考虑利用数组A是已经排序的条件,进行左右夹逼操作。在进行左右搜索的时候,须要将左右两边收缩到与当前元素不同的元素为止,这样做有两个原因:1.能够降低计算量;2.当当前的两个元素的和刚好等于-A[i]的时候,假设没有进行上面的缩放操作,那么就可能将反复的三个数保存下来,导致结果出错。



三.实现代码

  1. class Solution
  2. {
  3. public:
  4. vector<vector<int> > threeSum(vector<int> &num)
  5. {
  6. int Size = num.size();
  7.  
  8. vector<vector<int> > Result;
  9.  
  10. if (Size < 3)
  11. {
  12. return Result;
  13. }
  14.  
  15. sort(num.begin(), num.end());
  16.  
  17. for (int Index_outter = 0; Index_outter < (Size - 2); Index_outter++)
  18. {
  19. int First = num[Index_outter];
  20. int Second = num[Index_outter + 1];
  21. const int Target = 0;
  22.  
  23. if ((Index_outter != 0) && (First == num[Index_outter - 1]))
  24. {
  25. continue;
  26. }
  27.  
  28. int Start = Index_outter + 1;
  29. int End = Size - 1;
  30.  
  31. while (Start < End)
  32. {
  33. Second = num[Start];
  34. int Third = num[End];
  35.  
  36. int Sum = First + Second + Third;
  37.  
  38. if (Sum == Target)
  39. {
  40. vector<int> Tmp;
  41. Tmp.push_back(First);
  42. Tmp.push_back(Second);
  43. Tmp.push_back(Third);
  44.  
  45. Result.push_back(Tmp);
  46.  
  47. Start++;
  48. End--;
  49. while (num[Start] == num[Start - 1])
  50. {
  51. Start++;
  52. }
  53. while (num[End] == num[End + 1])
  54. {
  55. End--;
  56. }
  57.  
  58. }
  59.  
  60. if (Sum < Target)
  61. {
  62. Start++;
  63. while (num[Start] == num[Start -1])
  64. {
  65. Start++;
  66. }
  67. }
  68.  
  69. if (Sum > Target)
  70. {
  71. End--;
  72. if (num[End] == num[End + 1])
  73. {
  74. End--;
  75. }
  76. }
  77.  
  78. }
  79.  
  80. }
  81. return Result;
  82.  
  83. }
  84. };



四.体会

    我自己的想法时,将数组进行排序,然后依照顺序选择数组A[1, n-1)中的元素作为三个数中的中位数来在剩下的已经排好序的数组中寻找满足条件的其它两个数。可是。选择中位数的这样的情况须要考虑的边界条件比較复杂,并没有选择最小值来得方便一些。同一时候,选择中位数之后。将已经排序的数组分成了两段,这样在进行收缩的时候。须要分别推断两个两边与i的关系,也比較easy出错。

    这道题通过对数组进行排序。从而依照顺序选择不同的最小值来避免出现反复的情况。这确实是一个比較好的编程技巧。




版权全部,欢迎转载,转载请注明出处。谢谢



LeetCode_3Sum的更多相关文章

  1. LeetCode_3Sum Closest

    一.题目 3Sum Closest Total Accepted: 32191 Total Submissions: 119262My Submissions Given an array S of  ...

随机推荐

  1. Linux下安装MySQLdb模块(Python)

    一.MySQLdb-python模块 https://pypi.python.org/pypi/MySQL-python ` 二.安装依赖包 yum -y install python-devel m ...

  2. Dell Idrac Normal Settings

    racadm安装请查看:http://www.cnblogs.com/zyd112/p/7611022.html racadm语法(远程执行命令):racadm -r <racIpAddr> ...

  3. 【LeetCode】Unique Email Addresses(独特的电子邮件地址)

    这道题是LeetCode里的第929道题. 题目要求: 每封电子邮件都由一个本地名称和一个域名组成,以 @ 符号分隔. 例如,在 alice@leetcode.com中, alice 是本地名称,而  ...

  4. C. RMQ with Shifts

    C. RMQ with Shifts Time Limit: 1000ms Case Time Limit: 1000ms Memory Limit: 131072KB   64-bit intege ...

  5. TOJ 5020: Palindromic Paths

    5020: Palindromic Paths  Time Limit(Common/Java):10000MS/30000MS     Memory Limit:65536KByteTotal Su ...

  6. TheBrain8破解方式

    破解文件下载地址:http://rghost.net/51736270 mac破解方式: 我用的MAC 装的8007版本的,今天竟然提示要升级专业版本了.补救方法是,先打开TB,把之前手贱输入的云服务 ...

  7. 虚拟机搭建--hyper-V使用教程

    http://jingyan.baidu.com/article/4e5b3e19695d9f91901e24bb.html

  8. centos7 下修改网络配置

    修改ip地址 编辑 /etc/sysconfig/network-scripts/ifcfg-eth0 TYPE=Ethernet BOOTPROTO=static 静态ip DEFROUTE=yes ...

  9. UVa1363 Joseph's Problem

    把整个序列进行拆分成[k,k/2),[k/2, k/3), [k/3,k/4)...k[k/a, k/b)的形式,对于k/i(整除)相同的项,k%i成等差数列. /*by SilverN*/ #inc ...

  10. svn服务安装与配置

    SVN安装 centos系统下执行yum install subversion 创建项目 svnadmin create dxk-test 创建项目dxk-test 服务配置与权限控制 vim con ...