1. 程式人生 > >LintCode兩數之和,三數之和,四數之和

LintCode兩數之和,三數之和,四數之和

原文連結:http://www.cnblogs.com/eudiwffe/p/6282635.html

LintCode有大部分題目來自LeetCode,但LeetCode比較卡,下面以LintCode為平臺,簡單介紹我AC的幾個題目,並由此引出一些演算法基礎。

1)兩數之和(two-sum)

題目描述:

給一個整數陣列,找到兩個數使得他們的和等於一個給定的數 target

你需要實現的函式twoSum需要返回這兩個數的下標, 並且第一個下標小於第二個下標。注意這裡下標的範圍是 1 到 n,不是以 0 開頭。

注意:你可以假設只有一組解。

樣例:給出 numbers = [2, 7, 11, 15]

, target = 9, 返回 [1, 2],即數字2,7

程式碼介面:

1 2 3 4 5 6 7 8 9 10 11 class Solution { public: /* * @param numbers : An array of Integer * @param target : target = numbers[index1] + numbers[index2] * @return : [index1+1, index2+1] (index1 < index2)
*/ vector<int> twoSum(vector<int> &nums, int target) { // write your code here } };

常見的思路是:兩層for迴圈,任意兩個數組合求其和,判斷是否等於給定的target。但這樣太慢,需要O(n^2)的時間,O(1)的額外空間。可以反過來思考,假如當前選擇了一個數字a,那麼為了滿足條件,另一個數字b必須滿足:b=targe-a,即在陣列中尋找是否存在b。

如何快速尋找陣列中是否存在一個數字b?假如陣列是有序的,可以使用二分查詢

方法,其查詢時間複雜度是O(logn)。然而題目並沒給定這個條件。如果對陣列排序,首先就要O(nlogn)的時間進行排序,並且排序後,數字的原始下標也要儲存,顯然需要O(nlogn)的時間以及O(n)的空間,並不是最好的方法。

如何對一個數組進行快速查詢一個元素?演算法中提供了一種方法——雜湊(Hash),即對陣列中的每個元素按照某種方法(hash function)計算其“唯一”值id(稱為雜湊值),儲存在新的陣列A中(一般稱為雜湊陣列),並且其下標就是這個“唯一”值。那麼如果訪問A[id]存在,則這個元素存在,否則,原始陣列中不存在該元素。由於陣列是順序儲存的支援隨機訪問,所以查詢一個元素是否在陣列中,只需要O(1)的時間,但是在初始化雜湊陣列時,需要O(n)的時間和O(n)的空間。對於某些特定應用中,需要快速的時間,而對空間要求不苛刻時,雜湊陣列是一個非常好的方法。為了能夠滿足各種應用場景,又衍生出容量大小可以動態增長的雜湊集合(hash set)、雜湊對映(hash map),STL提供了關於雜湊的兩個類:unordered_set和unordered_map,前者只儲存元素,後者可以再增加額外的標誌資訊。詳細的內容,請自行補充。

由於構造的雜湊陣列,其元素的下標已經改變了,所以需要額外儲存元素原始的下標,因此此題使用unordered_map<int,int>,其儲存的內容為<元素值,元素原始下標>,詳細程式碼:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 class Solution {