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]
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?假如陣列是有序的,可以使用二分查詢
如何對一個數組進行快速查詢一個元素?演算法中提供了一種方法——雜湊(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
{
|