Acwing 800 陣列元素的目標和

2021-09-27 03:36:46 字數 1609 閱讀 2489

題目描述:

給定兩個公升序排序的有序陣列a和b,以及乙個目標值x。陣列下標從0開始。

請你求出滿足a[i] + b[j] = x的數對(i, j)。

資料保證有唯一解。

輸入格式

第一行包含三個整數n,m,x,分別表示a的長度,b的長度以及目標值x。

第二行包含n個整數,表示陣列a。

第三行包含m個整數,表示陣列b。

輸出格式

共一行,包含兩個整數 i 和 j。

資料範圍

陣列長度不超過100000。

同一陣列內元素各不相同。

1≤陣列元素≤10^9 

輸入樣例:

4 5 6

1 2 4 7

3 4 6 8 9

輸出樣例:

1 1
分析:

很容易想到暴力的做法,兩重迴圈依次列舉兩個陣列的位置,看能否找到和為x的位置。但是這種做法其一沒有用到兩個陣列的公升序性質,其二資料範圍是十萬,超過nlogn的演算法都會超時,於是尋求改進之法。

方法一:雜湊對映

遍歷一遍a陣列,將每個元素的值對映為在a中的下標,由於沒有重複元素,且資料量才十萬,雜湊對映不會占用太大空間且可行。之後再遍歷一遍b陣列,看看x-b[i]是否在a**現過。空間換時間,時空複雜度均為o(n)。

#include #include using namespace std;

const int maxn = 100005;

int a[maxn],b[maxn];

unordered_mapum;

int main()

return 0;

}

方法二:二分

方法一使用雜湊表同樣沒有利用上陣列有序的性質,並且由於查詢某元素是否在map中同樣耗時,所以效率並不高。而由有序的性質很容易想到遍歷a時可用二分法在b中查詢x-a[i]的位置。時間複雜度為o(nlogn)。

#include using namespace std;

const int maxn = 100005;

int a[maxn],b[maxn];

int main()

}if(b[l] + u == x) printf("%d %d\n",i,l);

}return 0;

}

方法三:雙指標

令指標p指向陣列a的第乙個位置,指標q指向陣列b的最後乙個位置,一旦a[p] + b[q]比x大,說明要減小其中一方的值,q--即可,如果比x小,p++即可,時間複雜度為o(n)。

思考下為什麼這次的雙指標要分別指向兩個陣列的開始和結束位置?因為若是開始p,q都指向陣列開頭,兩數和小於x時,是要該執行p++,還是q++呢?當兩數和大於x時,p,q肯定不能再往回移動了,而採取首尾指標的方法就能很好的解決了這一問題。

#include using namespace std;

const int maxn = 100005;

int a[maxn],b[maxn];

int main()

}return 0;

}

Acwing 800 陣列元素的目標和

給定兩個公升序排序的有序陣列a和b,以及乙個目標值x。陣列下標從0開始。請你求出滿足a i b j x的數對 i,j 資料保證有唯一解。輸入格式 第一行包含三個整數n,m,x,分別表示a的長度,b的長度以及目標值x。第二行包含n個整數,表示陣列a。第三行包含m個整數,表示陣列b。輸出格式 共一行,包...

AcWing 800 陣列元素的目標和

給定兩個公升序排序的有序陣列a和b,以及乙個目標值x。陣列下標從0開始。請你求出滿足a i b j x的數對 i,j 資料保證有唯一解。輸入格式 第一行包含三個整數n,m,x,分別表示a的長度,b的長度以及目標值x。第二行包含n個整數,表示陣列a。第三行包含m個整數,表示陣列b。輸出格式 共一行,包...

陣列元素的乘積

matlab prod 陣列元素的乘積 1 syntax a b prod a 返回陣列a的乘積 如果a是向量,prod a 返回a向量的乘積。如果a是非空矩陣,prod a 將a看作列向量,返回每一列元素的乘積並組成乙個行向量b。如果a是空矩陣,prod a 返回1。如果a是多維陣列,prod a...