題目描述:輸入乙個陣列和乙個數字,在陣列中查詢兩個數,使得它們的和正好是輸入的那個數字。
要求時間複雜度是o(n)。如果有多對數字的和等於輸入的數字,輸出任意一對即可。
例如輸入陣列1、2、4、7、11、15和數字15。由於4+11=15,因此輸出4和11。
下面給出這個題的不同解法(注意闡述中數列有序無序的區別):
(1)這個題目相當於,對每個a[i],查詢sum-a[i]是否也在原始序列中,每一次要查詢的時間都要花費為o(n),這樣下來,最終找到兩個數還是需要o(n^2)的複雜度(相當於用了兩層for迴圈)。那如何提高查詢判斷的速度呢?答案是二分查詢,可以將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)序列有序前提下:在思路1基礎上還有一種更快的方法,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
要達到o(n)的複雜度(注意:這個o(n)的時間複雜度是基於原始序列有序的情況下,否則還是o(n*logn)的時間複雜度,因為排序要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再進行判斷,直到它們到達邊界。
(3)當然,還可以構造hash表,正如程式設計之美上的所述,給定乙個數字,根據hash對映(雜湊函式就是乙個減式)查詢另乙個數字是否也在陣列中,只需用o(1)的時間,這樣的話,總體的演算法通上述思路2 一樣,也能降到o(n),但有個缺陷,就是構造hash額外增加了o(n)的空間,此點同上述思路 2。不過,空間換時間,仍不失為在時間要求較嚴格的情況下的一種好辦法。
(4)如果陣列是無序的,先排序(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]時間複雜度最終為o(n*logn+n)=o(n*logn),若原陣列是有序的,則不需要事先的排序,直接o(n)搞定,且空間複雜度還是o(1),此思路是相對於上述所有思路的一種改進。(如果有序,直接兩個指標兩端掃瞄,時間o(n),如果無序,先排序後兩端掃瞄,時間o(n*logn+n)=o(n*logn),空間始終都為o(1))。(與上述思路1相比,排序後的時間開銷由之前的二分的n*logn降到了掃瞄的o(n))。
總結:
二分(若無序,先排序後二分),時間複雜度總為o(n*logn),空間複雜度為o(1);(如:思路1)
掃瞄一遍x-s[i] 對映到乙個陣列或構造hash表,時間複雜度為o(n),空間複雜度為o(n);(如:思路2和3)
兩個指標兩端掃瞄(若無序,先排序後掃瞄),時間複雜度最後為:有序o(n),無序o(n*logn+n)=o(n*logn),空間複雜度都為o(1)。(如:思路4)
參考文章:這篇博主是真的厲害,膜拜!!!
陣列 尋找和為定值的兩個數
題目描述 給定乙個陣列和乙個整數,要求在陣列中找到兩個數,使得它們的和為這個整數.方法 排序夾逼 首先使用快速排序演算法把陣列按公升序排列,然後使用夾逼的方法找到答案.即使用兩個指標分別指向陣列的頭和尾 begin,end 1.若arr begin arr end sum 就輸出 2.若arr be...
尋找和為定值的兩個數
尋找和為定值的兩個數 給定乙個陣列 無序或者有序,兩種情況都要考慮 找出和為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 可以換乙個思...