標籤:leetcode hashmap
題目:
Given an array of integers, find two numbers such that they add up to a specific target number.
The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are not zero-based.
You may assume that each input would have exactly one solution.
Input: numbers={2, 7, 11, 15}, target=9
Output: index1=1, index2=2
分析1:
題目要求很明確,給出一組整型數組(沒有順序, 有可能有重複的值,並且有可能有負數),找到兩個其中的數,使得它們的和為所給的target。順序輸出那兩個數的下標。每組數組有且只有一組答案。
一開始看了題目就直接寫了兩個for迴圈搞定,代碼如下。然後興高采烈的提交代碼,結果就悲劇了。
系統給的錯誤是Time Limit Exceeded,所用的測試數組元素個數為10000,兩個for迴圈算完花都謝了。
vector<int> twoSum(vector<int> &numbers, int target) { vector<int> indexs; vector<int> res; bool flag = true; for (int i=0; i<numbers.size()-1 && flag; i++) { for (int j=i+1; j<numbers.size(); j++) { if(numbers[i] + numbers[j] == target) { res.push_back(i+1); res.push_back(j+1); flag = false; break; } } } return res; }
分析2:
這個問題看似要找兩個數,但是可以轉換一下變成找一個數的問題。而對一個元素個數很大的數組,要快速找到其中的某個數,還是得用HashMap。於是有了第二種演算法,代碼如下:
vector<int> twoSum(vector<int> &numbers, int target) { vector<int> res(2,0); unordered_map<int, int> numbersMap; for(int i=0; i<numbers.size(); i++) numbersMap[numbers[i]] = i; unordered_map<int, int>::const_iterator iter = numbersMap.end(); for (int i=0; i<numbers.size(); i++) { int minus = target - numbers[i]; iter = numbersMap.find(minus); if (iter != numbersMap.end() && iter->second != i) { if (i < iter->second) { res[0] = i+1; res[1] = iter->second + 1; } else { res[0] = iter->second + 1; res[1] = i + 1; } } } return res; }
unordered_map<int, int>的Key和Value都是整型資料,我以numbers中的資料作為Key,然後以相應的下標作為Value, 建立並初始化了一個map。這裡有一個問題是,numbers中有可能有相同的值,相同的值在map中的Key一樣,但是對應的Value不一樣。unordered_map內部應該有處理這種衝突了,所以不用擔心這個問題。
還需要注意的是,當找到要找的數(minus)時,一定要根據下標判斷一下是否跟number[i]是同一個數,如果下標相同,則還沒找到。
if (iter != numbersMap.end() && iter->second != i)
下面是完整代碼,包括測試:
#include <iostream>#include <vector>#include <unordered_map>using namespace std;vector<int> twoSum(vector<int> &numbers, int target){vector<int> res(2,0);// 建立並初始化HashMap,以numbers的每個值作為key,而value是相對應的下標。// numbers中的值有可能相同,但相同的值對應的下標不同。unordered_map<int, int> numbersMap;for(int i=0; i<numbers.size(); i++)numbersMap[numbers[i]] = i;unordered_map<int, int>::const_iterator iter = numbersMap.end();for (int i=0; i<numbers.size(); i++){// 求差並以差值為key尋找int minus = target - numbers[i];iter = numbersMap.find(minus);if (iter != numbersMap.end() && iter->second != i) // 看是否找到了,而且還要判斷找到的是否是同一個值{if (i < iter->second){res[0] = i+1;res[1] = iter->second + 1;}else{res[0] = iter->second + 1;res[1] = i + 1;}}}return res;}int _tmain(int argc, _TCHAR* argv[]){int target = 9;vector<int> numbers;numbers.push_back(2);numbers.push_back(7);numbers.push_back(11);numbers.push_back(15);vector<int> res = twoSum(numbers, target);// 測試結果for (int i=0; i<res.size(); i++)cout << res[i] << " ";cout << endl;return 0;}
對於HashMap其實瞭解不多,要認真研究一下才行!