尋找兩個數的和為定值的演算法

2021-07-03 15:51:34 字數 1703 閱讀 9017

題目:輸入乙個陣列和乙個數字,在陣列中查詢兩個數,使得它們的和正好是輸入的那個數字。

要求時間複雜度是o(n)。如果有多對數字的和等於輸入的數字,輸出任意一對即可。

例如輸入陣列1、2、4、7、11、15和數字15。由於4+11=15,因此輸出4和11。

直接窮舉,從陣列中任意選取兩個數,判定它們的和是否為輸入的那個數字。此舉複雜度為o(n^2)。很顯然,我們要尋找效率更高的解法。

題目相當於,對每個a[i],查詢sum-a[i]是否也在原始序列中,每一次要查詢的時間都要花費為o(n),這樣下來,最終找到兩個數還是需要o(n^2)的複雜度。那如何提高查詢判斷的速度呢?答案是二分查詢,可以將o(n)的查詢時間提高到o(logn),這樣對於n個a[i],都要花logn的時間去查詢相對應的sum-a[i]是否在原始序列中,總的時間複雜度已降為o(n*logn),且空間複雜度為o(1)。(如果有序,直接二分o(n*logn),如果無序,先排序後二分,複雜度同樣為o(n*logn+n*logn)=o(n*logn),空間總為o(1))。有沒有更好的辦法呢?咱們可以依據上述思路2的思想,a[i]在序列中,如果a[i]+a[k]=sum的話,那麼sum-a[i](a[k])也必然在序列中,舉個例子,如下:

原始序列:1、 2、 4、 7、11、15     用輸入數字15減一下各個數,得到對應的序列為:

對應序列:14、13、11、8、4、 0      

第乙個陣列以一指標i 從陣列最左端開始向右掃瞄,第二個陣列以一指標j 從陣列最右端開始向左掃瞄,如果下面出現了和上面一樣的數,即a[*i]=a[*j],就找出這倆個數來了。如上,i,j最終在第乙個,和第二個序列中找到了相同的數4和11,,所以符合條件的兩個數,即為4+11=15。怎麼樣,兩端同時查詢,時間複雜度瞬間縮短到了o(n),但卻同時需要o(n)的空間儲存第二個陣列(@飛羽:要達到o(n)的複雜度,第乙個陣列以一指標i 從陣列最左端開始向右掃瞄,第二個陣列以一指標j 從陣列最右端開始向左掃瞄,首先初始i指向元素1,j指向元素0,誰指的元素小,誰先移動,由於1(i)>0(j),所以i不動,j向左移動。然後j移動到元素4發現大於元素1,故而停止移動j,開始移動i,直到i指向4,這時,i指向的元素與j指向的元素相等,故而判斷4是滿足條件的第乙個數;然後同時移動i,j再進行判斷,直到它們到達邊界)。

當然,你還可以構造hash表,正如程式設計之美上的所述,給定乙個數字,根據hash對映查詢另乙個數字是否也在陣列中,只需用o(1)的時間,這樣的話,總體的演算法通上述思路3 一樣,也能降到o(n),但有個缺陷,就是構造hash額外增加了o(n)的空間,此點同上述思路 3。不過,空間換時間,仍不失為在時間要求較嚴格的情況下的一種好辦法。

如果陣列是無序的,先排序(n*logn),然後用兩個指標i,j,各自指向陣列的首尾兩端,令i=0,j=n-1,然後i++,j--,逐次判斷a[i]+a[j]?=sum,如果某一刻a[i]+a[j]>sum,則要想辦法讓sum的值減小,所以此刻i不動,j--,如果某一刻a[i]+a[j]

總結

pair findsum(int *s,int n,int x)     

else if(*begin+*endbegin)

else if(current_sum > sum)

end--;

else

begin++;

} return false;

}

尋找和為定值的兩個數

尋找和為定值的兩個數 給定乙個陣列 無序或者有序,兩種情況都要考慮 找出和為m的兩個數。最多時間複雜度能有多少?陣列有序的情況,在時間複雜度上我們就省去了排序的o nlogn 我們使用兩端指標掃瞄法是比較簡單的,時間複雜度為o n 空間複雜度為o 1 如下圖所示 然後,判斷它們指向的值之和sum是否...

尋找和為定值的兩個數

描述 輸入乙個陣列和乙個數字,在陣列中查詢兩個數,使得它們的和正好是輸入的那個數字。要求時間複雜度是o n 如果有多對數字的和等於輸入的數字,輸出任意一對即可。例如輸入陣列1 2 4 7 11 15和數字15。由於4 11 15,因此輸出4和11。分析 如果採取窮舉,複雜度為o n 2 可以換乙個思...

尋找和為定值的兩個數

題目 輸入乙個陣列和乙個數字,在陣列中查詢兩個數,使得它們的和正好是輸入的那個數字。要求時間複雜度是o n 如果有多對數字的和等於輸入的數字,輸出任意一對即可。例如輸入陣列1 2 4 7 11 15和數字15。由於4 11 15,因此輸出4和11。解析 如果陣列是無序的,先排序 n logn 然後用...