題目描述:
給定兩個公升序排序的有序陣列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...