N-sum Problem
源代码push到了github上,戳这里
N-sum 专题
1 sum
题目描述:在给定序列里寻找一个数,使之等于target,返回该数.
解法:将数组排序,二分查找, 时间复杂度O(logn)
解法二: 当然,如果找到一个比较好的hash函数或者hashtable, O(1)的复杂度就可以找到.
下述所有的涉及二分查找的方法都可以用hash法代替,故不讨论.
2 sum
题目描述: 在给定序列中寻找所有满足且不重复的元组(x,y),x <= y,使得 x + y == target
解法一: 参照 1 sum 的思路,先排序,固定住a,此时只要在数组中二分寻找存不存在数(target - x)即可
解法二: 对于一个有序数组 a <= b <= c <= d, 我们可以发现以下的不等式成立:
a + d <= b + d
a + d >= a + c
设想如果有两个指针start,end, start指向a, end指向d,如果此时start + end < target,那么依据上面的不等式,只需要将start指针迁移,后面的和一定比前面的和大.这样在O(n)的时间内就可以搞定. 排序的时间复杂度是O(nlogn),那么总的复杂度还是O(nlogn).这种思想在后面会用到.
3 sum
题目描述: 在给定序列中寻找所有满足且不重复的元组(x,y,z),x <= y <= z,使得 x + y + z == target
经过上面的推导,显然此题也有两种解法.对于解法一,固定住x,y,二分查找z,时间复杂度是O(n2logn).对于解法二,固定住x,问题就便成了2 sum的问题.时间复杂度为O(n2).
4 sum
对于此问题而言,可以延续上面的解法,但是偶数-sum问题可以做一下化简.将数组两两之和求出来,形成新的数组,在新的数组里面只要找出两个数之和等于target即可.即4 sum问题转化为了 2 sum + 2 sum的问题.上述两种方法随便挑.时间复杂度都是O(n2).
N sum
显然,可以将N sum问题拆分成 N - i sum 和 N sum 两个问题求解,酌情考虑.
Leetcode 18: 3Sum
如上面所讨论的,我的实现是采用了第两个指针的方法.
Leetcode 19: 4Sum
如上面讨论,我的实现是转化成了 3 sum 问题,时间复杂度是O(n3).
Leetcode 20: 3Sum Closest
题目描述: 和3 sum不同的唯一一点就是,他要在数组中找3个数,使得和最接近target.输出这个和.
解法:大体思想不变.我用的是两个指针的方法,那么每次只要取 abs(target - sum)的最小值,并在更新的时候记录这个差是正的还是负的(和比target大还是小).