いくつかのソリューションからアルゴリズムアルゴリズムの最適化のアイデアについての質問を体験してください。。。
トピック:
この問題は最初の考えを参照するには家主は暴力です。
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;
}
};
単一のテストケースにより、
より大きな入力アレイに対して、時間制限を超え
暴力時間複雑さはO(n ^ 4)であり、複雑さのレベルは、全ての場合において方法、高速検索する必要性を使用することができません。
家主最初に考え+は[ジエチル分で標的0-A [i]が-Bを検索、配列Dのソート後に、特に、時間複雑度はO(n ^ 3 *ログ(n))がダウンバイナリ検索を使用してソートJ] -C上限と下限の[k]は、Dアレイを横断回避します。次のことを達成するために:
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;
}
};
残念ながら、すべてのテストケースは依然として通過できないが、対照的暴力は、許容時間内に試験、試験方法によるさらなるユースケース(23 <46)は、二分探索+が働いて最適化さソートすることができます。
だから我々は、より高速なアルゴリズムを必要とします。このアプローチを使用するために今、私たちは、それは可能な限り、バイナリサーチアルゴリズムを最適化できることを知っていること?我々はTetrameles合計は(A [I] + B [j])に変換し、及び(C [K] + D [L])、Nを使用して* Nサイズの配列を格納CD =(C [K] +することができD [L])、ここでのソートCD、ルック - ([I] + B [j])上限と下限のは、問題に対する解決策を与えます。次のことを達成するために:
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;
}
/*二分查找算法与之前的相同,此处省略*/
};
(A [I] + B [j])はO(n ^ 2 *ログ( - O(N ^ 2)+ CDソートO(ログ(N ^ 2))+ CDルックアップの構成CDアレイから計算複雑N ^ 2))、最高レベルであるが、O(N ^ 2 *ログ(N ^ 2))のレベルを向上させるために、線形最適化法の比較です。テスト結果:
これは、すべてのユースケースを渡されたが、唯一のレコード以上の58.35パーセントを提出し、もはや導入された多くの最適化プログラムがありますが、私たちは、コメントがそれを指摘歓迎します!