Experience from several solutions a question about the algorithm algorithm optimization ideas. . .
topic:
Landlord to see this problem first thought is Violence:
class Solution {
public:
int fourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D) {
int ans=0;
for(int i=0; i<A.size(); i++){
for(int j=0; j<B.size(); j++){
for(int k=0; k<C.size(); k++){
for(int l=0; l<D.size(); l++){
if(A[i]+B[j]+C[k]+D[l]==0)
ans++;
}
}
}
}
return ans;
}
};
By a single test case
But for larger input array, exceed the time limit
Violence time complexity is O (n ^ 4), the level of complexity can not be used in all cases the method, need to find a faster.
Landlord first thought + sorted using the binary search down time complexity O (n ^ 3 * log (n)), in particular after the array D sort, search target 0-A [i] -B with diethyl minutes [ j] -C [k] of the upper and lower bounds, to avoid traversing D array. To achieve the following:
class Solution {
public:
int fourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D) {
int ans=0;
sort(D.begin(), D.end());
for(int i=0; i<A.size(); i++){
for(int j=0; j<B.size(); j++){
for(int k=0; k<C.size(); k++){
int lb=lowborder(D, 0-A[i]-B[j]-C[k]), hb=highborder(D, 0-A[i]-B[j]-C[k]);
if(lb!=-1)
ans+=hb-lb+1;
}
}
}
return ans;
}
int highborder(vector<int>& nums, int target){
int lo=0, hi=nums.size()-1;
while(lo<=hi){
int mi=lo+(hi-lo)/2;
if(nums[mi]<target)
lo=mi+1;
else if(nums[mi]>target)
hi=mi-1;
else
lo=mi+1;
}
if(lo-1>=0&&nums[lo-1]==target)//注意加限制lo-1的条件
return lo-1;
else
return -1;
}
int lowborder(vector<int>& nums, int target){
int lo=0, hi=nums.size()-1;
while(lo<=hi){
int mi=lo+(hi-lo)/2;
if(nums[mi]<target)
lo=mi+1;
else if(nums[mi]>target)
hi=mi-1;
else
hi=mi-1;
}
if(hi+1<=nums.size()-1&&nums[hi+1]==target)//注意加hi+1的限制条件
return hi+1;
else
return -1;
}
};
Unfortunately, all the test cases still can not pass, but the contrast Violence, within the allowed time test, the test method can further use cases (23 <46), with the sorted binary search + optimized worked.
So we need a faster algorithm. Now that we know binary search algorithm can be optimized, Can it as much as possible to use this approach? We can Tetrameles sum converted to (A [i] + B [j]), and (C [k] + D [l]), using a n * n sized array stores CD = (C [k] + D [l]), a CD sort, and look at where - (a [i] + B [j]) of the upper and lower bounds, to give solution to the problem. To achieve the following:
class Solution {
public:
int fourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D) {
int ans=0;
vector<int> CD;
for(int k=0; k<C.size(); k++)
for(int l=0; l<D.size(); l++)
CD.push_back(C[k]+D[l]);
sort(CD.begin(), CD.end());
for(int i=0; i<A.size(); i++){
for(int j=0; j<B.size(); j++){
int lb=lowborder(CD, 0-A[i]-B[j]), hb=highborder(CD, 0-A[i]-B[j]);
if(lb!=-1)
ans+=hb-lb+1;
}
}
return ans;
}
/*二分查找算法与之前的相同,此处省略*/
};
Calculation complexity from the configuration CD array of O (n ^ 2) + CD sort O (log (n ^ 2)) + CD lookup - (A [i] + B [j]) O (n ^ 2 * log ( n ^ 2)), which is the highest level is O (n ^ 2 * log (n ^ 2)) on a comparison of a linear optimization method to improve the level. Test Results:
It passed all use cases, but only to submit more than 58.35% of the records, there are more optimization program no longer introduced, but we welcome comments pointed out that!