題目描述:輸入乙個遞增排序的陣列和乙個數字s,在陣列中查詢兩個數,是的他們的和正好是s,如果有多對數字的和等於s,輸出兩個數的乘積最小的。
輸入:每個測試案例包括兩行:
第一行包含乙個整數n和k,n表示陣列中的元素個數,k表示兩數之和。其中1 <= n <= 10^6,k為int
第二行包含n個整數,每個陣列均為int型別。
輸出:對應每個測試案例,輸出兩個數,小的先輸出。如果找不到,則輸出「-1 -1」
樣例輸入:
6 151 2 4 7 11 15
樣例輸出:
4 11
解決這個問題有一下四種方法:
1、對每乙個數字遍歷其後的每乙個數字,看看有沒有符合要求的數字。這種方法的時間複雜度為o(n^2)。
2、在1的基礎上,查詢數字的時候採用二分查詢,這樣的話時間複雜度為o(nlogn)。
3、在一定的限制條件下,比如陣列的最大是已知的,那麼就可以你用建hash表的方法。首先建立hash表,時間複雜度為o(1),然後對每乙個數字a查詢sum-a是否在表中,這個時間複雜度為o(1),所以總的時間複雜度為o(n)。
4、先設兩個變數i=0,j=n-1,然後判斷a[i]+a[j]的值與sum的大小,(1)如果大小剛好合適,則判斷乘積是否更小,如果更小則更新結果,否則不更新。 (2)如果比sum的值大,則i++,否則j--。剛開始接觸這個演算法,我對它的正確性表示懷疑,懷疑會不會漏掉元素,後來看到別人的證明方法。證明方法如下:
假設有這樣乙個陣列a,6,14,15,28,a,35,54,b,57,58。我們要求的sum等於a+b。在程式執行的過程中總有乙個標記會先到正確的位置(i到a處、j到b處都是正確的位置),假設i先到達a處,j必然沒有到b處,則a[i]+a[j]的和大於sum,所以後面就會對j--,最終j就可以到b處;同理j先到也一樣。
程式c++**:
#include #include const int n=1000010;
long int arr[n];
int main(){
long int n,k,j,i;//freopen("1.txt","r",stdin);
while(scanf("%ld%ld",&n,&k)!=eof){
for(j=0;j
和為S的兩個數字
輸入乙個遞增排序的陣列和乙個數字s,在陣列中查詢兩個數,是的他們的和正好是s,如果有多對數字的和等於s,輸出兩個數的乘積最小的。輸出描述 對應每個測試案例,輸出兩個數,小的先輸出。class solution public vectorfindnumberswithsum vectorarray,i...
和為s的兩個數字
輸入乙個遞增排序的陣列和乙個數字s,在陣列中查詢兩個數,是的他們的和正好是s,如果有多對數字的和等於s,輸出兩個數的乘積最小的。輸出描述 對應每個測試案例,輸出兩個數,小的先輸出。include using namespace std bool twonumberwithsum int data,i...
和為S的兩個數字
輸入乙個遞增排序的陣列和乙個數字s,在陣列中查詢兩個數,使得他們的和正好是s,如果有多對數字的和等於s,輸出兩個數的乘積最小的。輸出描述 對應每個測試案例,輸出兩個數,小的先輸出 思路 數列滿足遞增,設兩個頭尾兩個指標i和j,若ai aj sum,就是答案 相差越遠乘積越小 若ai aj sum,a...