問題爲知道一個數組A[n],和一數字k,存在唯一一對數字A[i] +A[j]= k;
求出這樣的數字的對數,如A{1,2,3,4,5,4,1,6,7} k=13 求得的結果爲 13=3+7;
首先經好想的方法就是暴力,枚舉任意兩個數字的和 與k比較
for(int i=0;i<n-1;i++)
for(int j=i+1;j<n;j++)
if( ( A[i]+A[j] )==k){
cout<<a[i]<<" "<<a[j]<<emd;
break;
}
但是這不是最好的解法,O(n^2)的時間複雜度有點慢了,
於是想到用hash試試,這裏用set進行求解,
因爲set用紅黑樹實現的,不管是插入還是查找的效率都很可觀的
對數組掃描一遍,(假設已經定義好了 set< int >m)
對於數字A[i] 首先做 m.find(A[i]) 操作,如果反會值爲m.end();
說明集合中還沒有A[i]元素,那麼我們在進行m.find( k-A[i] ) 操作,
如果返回不爲m.end(),說明有元素與A[i]匹配並相加爲k,那麼ans+1.
需要特殊注意的是m.find(A[i]) != m.end() ,說名集合中已經有一個元素值爲A[i]了
這時需要注意 k= a + a 情況,如(8 = 4 + 4)
根據上面的分析 可以很快寫出代碼來:
set<int >m;
void func(int *A, int n, int k){
for(int i=0;i<n;i++){
if(m.insert(A[i])== m.end()){
if(m.find( k- A[i] )!=m.end() ){
cout<<k-A[i]<< " "<<A[i]<<endl;
break;
}else{
m.insert(A[i]);
}
}else{
if(k== A[i]+ A[i]){
cout<<A[i]<<" "<<A[i]<<endl;
break;
}
}
}
}
當然對於這類問題的變形,如數組中存在多對數字相加得k,需要求的是存在的對數,我們可以用map一樣可以得到較高效的解。