在陣列中尋找和為指定值的兩個數

一隻鳥的天空發表於2014-05-11

題目:在陣列中尋找和為指定值的兩個數,如arr={1, 2,3,4,7,8} ,指定值sum為12,返回4+8=12

方法1:

採用暴力破解(即窮舉),時間複雜度為O(n*n),即對每一個數arr[i],搜尋sum-arr[i]在不在陣列中。

方法2:

根據方法1,如果陣列已經排好序,可以使用二分查詢sum-arr[i];如果沒有排好序可以使用某種排序演算法對其先進行排序(如平均複雜度為nlogn的快排(取決於劃分元的選擇,可以選取第一個,或者第一個和中間元素和最後一個的中位數,或者隨機選取,或者按照BFPRT演算法那樣選取等),nlogn的堆排序或者歸併排序等)。時間複雜度為nlogn。

方法3:

可以採用Hash表儲存,對於每一個元素arr[i],在Hash表中查詢sum-arr[j]是否存在,因為Hash查詢的時間複雜度為O(1),所以期望的時間複雜度為O(n),但是因為Hash表空間有限,所以會產生衝突,解決衝突的方法有連結串列法和開放地址法等,比如連結串列法在極端情況下,所有元素都存在一個鏈中,那麼就退化為O(n*n),這取決於Hash函式與Hash表的空間大小。這是典型的用空間換取時間。

方法4:

如果只是陣列中最多存在一對這樣的數,便可以採取下面的方法:

比如arr={1,2,3,4,7,8},sum=12

首先求得sum-arr={11,10,9,8,5,4}

然後定義兩個索引標號i與j,i從arr頭開始向後移動,j從sum-arr尾開始向前移動,哪個指向的元素小,就先移動到大於等於另一個指向的元素,如果兩個指向的元素相等,則選出該元素,繼續移動,直到到達邊界。選中的兩個元素便是結果,如果選出的元素個數小於2則該陣列中沒有符合條件的。但是該方法有個缺陷,如果含有多對符合條件的元素對,那麼最後要從選出的結果中繼續尋找。

方法5:

如果陣列是無序的,則可以先進行排序(nlogn)。然後定義兩個索引標號i與j,分別指向排序後的陣列的頭和尾,然後i向後移動(++i),j向前移動(++j),到i>=j則停止。

   如果arr[i]+arr[j]=sum,則找到了一對,然後++i和++j,繼續尋找;

   如果arr[i]+arr[j]>sum,則--j;

   如果arr[i]+arr[j]<sum,則++i;

到i>=j則停止。

時間複雜度為O(n)。

相關文章