6.3Sum && 4Sum [ && K sum ] && 3Sum Closest

3Sum

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.
    For example, given array S = {-1 0 1 2 -1 -4},

    A solution set is:
(-1, 0, 1)
(-1, -1, 2)

解析:分三步: a.排序.       b. 任取一个没取过的数,余下右边的序列中求 2Sum.       c. 取2Sum的过程中,应保证没有重复。

// O(n^2 + nlogn) // no set used!
class Solution {
public:
vector<vector<int> > threeSum(vector<int> &num) {
vector<vector<int> > vec;
vector<int> vec2(3, 0);
int n = num.size();
if(n < 3) return vec;
sort(num.begin(), num.end());
/* promise not occur again */
int preValue = num[0] + 1;
for(int i = 0; i < n-2; ++i){
if(num[i] == preValue) continue;
else preValue = num[i];
/* 2Sum */
int j = i + 1, k = n-1;
while(j < k ){
int sum = num[j] + num[k] + num[i];
if(sum== 0){
vec2[0] = num[i]; vec2[1] = num[j]; vec2[2] = num[k];
while(j < k && num[j] == num[j+1]) ++j; // promise not occur again
while(j < k && num[k] == num[k-1]) --k;
vec.push_back(vec2);
++j,--k;
}else if(sum < 0){
++j;
} else --k;
}
}
return vec;
}
};

 

 4Sum

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

Note:

  • Elements in a quadruplet (a,b,c,d) must be in non-descending order. (ie, a ≤ b ≤ c ≤ d)
  • The solution set must not contain duplicate quadruplets.
    For example, given array S = {1 0 -1 0 -2 2}, and target = 0.

    A solution set is:
(-1, 0, 0, 1)
(-2, -1, 1, 2)
(-2, 0, 0, 2)

解析:3Sum 之上加一层循环。

 class Solution {
public:
vector<vector<int> > fourSum(vector<int> &num, int target) {
vector<vector<int> > vec;
vector<int> ans(, ); // record one answer
int n = num.size();
if(n < ) return vec;
sort(num.begin(), num.end());
int preVal4 = num[] ^ 0x1;
for(int i = ; i < n - ; ++i){
if(num[i] == preVal4) continue;
else preVal4 = num[i];
int preVal3 = num[i+] ^ 0x1;
for(int j = i+; j < n - ; ++j){
if(num[j] == preVal3) continue;
else preVal3 = num[j];
int s = j + , t = n - , target2 = target - num[i] - num[j];
while(s < t){
int sum = num[s] + num[t];
if(sum == target2){
ans[] = num[i]; ans[] = num[j]; ans[] = num[s]; ans[] = num[t];
while(s < t && num[s] == num[s+]) ++s;
while(s < t && num[t] == num[t-]) --t;
vec.push_back(ans);
++s, --t;
}else if(sum < target2) {
++s;
}else --t;
}
}
}
return vec;
}
};

Code

kSum(刷题模版)

class Solution {
public:
vector<vector<int> > kSum(vector<int> &num,int k, int target) {
vector<vector<int> > vec;
vector<int> vec2;
if(num.size() < k) return vec;
sort(num.begin(), num.end());
getSum(vec, vec2, num, 0, k, target);
return vec;
} void getSum(vector<vector<int> > &vec, vector<int> &vec2, vector<int> &num, int begin, int k, int target){
if(k == 2){
int len = num.size(), s = begin, t = len - 1;
while(s < t){
int sum = num[s] + num[t];
if(sum == target){
vec2.push_back(num[s]); vec2.push_back(num[t]);
while(s < t && num[s] == num[s+1]) ++s;
while(s < t && num[t] == num[t-1]) --t;
vec.push_back(vec2);
vec2.pop_back(); vec2.pop_back(); // key
++s, --t;
}else if(sum < target) {
++s;
}else --t;
} }else {
int len = num.size();
int preValue = num[begin] ^ 0x1;
for(int start = begin; start < len-k+1; ++start){
if(num[start] == preValue) continue;
else preValue = num[start];
vec2.push_back(num[start]);
getSum(vec, vec2, num, start + 1, k - 1, target - num[start]);
vec2.pop_back();
}
}
}
};

算法复杂度分析:

k-SUM can be solved more quickly as follows.

  • For even k: Compute a sorted list S of all sums of k/2 input elements. Check whether S contains both some number x and its negation −x. The algorithm runs in O(nk/2logn) time.

  • For odd k: Compute the sorted list S of all sums of (k−1)/2 input elements. For each input element a, check whether S contains both x and a−x, for some number x. (The second step is essentially the O(n2)-time algorithm for 3SUM.) The algorithm runs in O(n(k+1)/2) time.

Both algorithms are optimal (except possibly for the log factor when k is even and bigger than 2) for any constant k in a certain weak but natural restriction of the linear decision tree model of computation.

3Sum Closest

Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input would have exactly one solution.

    For example, given array S = {-1 2 1 -4}, and target = 1.

    The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).
class Solution {
public:
int threeSumClosest(vector<int> &num, int target) {
int len = num.size();
if(len < 3){
printf("Number of elements is less than 3.\n");
return 0;
}
sort(num.begin(), num.end());
int minDiff = 0x7fffffff; // note: a = 0x80000000; abs(a) == -2147483648;
int preValue3 = num[0] + 1; // jump the number appeared again.
for(int i = 0; i < len - 2; ++i){
if(num[i] == preValue3) continue;
else preValue3 = num[i]; int s = i + 1, t = len - 1, temVal = num[i] - target;
while(s < t){
int curDiff = temVal + num[s] + num[t];
if(curDiff == 0) return target;
else if(curDiff < 0) ++s;
else --t; if(abs(curDiff) < abs(minDiff)) minDiff = curDiff;
}
}
return target + minDiff;
}
};
上一篇:在MTK平台里,,函数kal_prompt_trace起什么作用???Kal_prompt_trace的参数有表示什么?


下一篇:java中得到图片的宽度 高度: