57.3Sum
1.Description(Medium)
Given an array S_of n integers, are there elements a,b, c in S such thata + b + c = 0.
Find all unique triplets in the array which gives the sum of zero.
Notice
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.
Example
For example, given array S ={-1 0 1 2 -1 -4}
, A solution set is:
2.Code
Version 1:
经典题目,先排序array,利用a+b=-c,遍历array,使每次的integer = -c,从两头寻找a和b使得a+b=-c。主要难点在于duplicate solution的处理。(因为array里面的值有重复的)此解法复杂度为O(n^2)。
这道题让我们求三数之和,比之前那道要复杂一些,我们还是要首先对原数组进行排序,然后开始遍历排序后的数组,这里注意不是遍历到最后一个停止,而是到倒数第三个就可以了,然后我们还要加上重复就跳过的处理,对于遍历到的数,我们用0减去这个数得到一个sum,我们只需要再之后找到两个数之和等于sum即可,这样一来问题又转化为了求two sum,这时候我们一次扫描,找到了等于sum的两数后,加上当前遍历到的数字,按顺序存入结果中即可,然后还要注意跳过重复数字。题目要求的是a+b+c=0,问题可以推广到a+b+c=target。3sum问题可以转化为2sum问题:对于任意一个A[i],在数组中的其他数中解2sum问题,目标为target-A[i]。与2sum那题不同,这题要求返回的不是index而是数字本身,并且解不唯一。同时要求解排序并去重。
对排序来说,2sum中的双指针法更为方便,因为算法本身就用到排序。双指针排序法本身会去除一些重复的可能性:
(1, 2, 3, 4), target = 6
在扫描1时,解(2, 3, 4)的2sum = 5问题,找到一个解(1, 2, 3)。
在扫描2时,应当只对后面的数解2sum问题,即对(3, 4)解2sum = 4问题。这样避免再次重复找到解(1, 2, 3)。
但当存在重复数字时,光靠排序仍然无法去重:
(1, 2, 2, 2, 3, 4), target = 9
扫描第一个2时,解(2, 2, 3, 4)中的2sum=7问题,得到解(2, 3, 4)
扫描第二个2时,解(2, 3, 4)中的2sum=7问题,仍然会得到(2, 3, 4)
去除因重复数字而造成重复解有两个办法,
一是将结果存到一个hashset。
而另一种方法就是在扫描数组时跳过重复的数字。上例中,只扫描1, 2, 3, 4来求相应的2sum问题。进一步简化,可以只扫描1, 2。因为3已经是倒数第二个数字,不可能有以它为最小数字的解。
这里注意两次avoid duplicate solution,一次是在选择target的时候,一次是在内循环里面在剩余的array中寻求 2 sum 的解的时候
Version 2: 套用 NSum 模板
Last updated