題目描述:
給定一個整數數組 nums 和一個目標值 target,請你在該數組中找出和爲目標值的那 兩個 整數,並返回他們的數組下標。
你可以假設每種輸入只會對應一個答案。但是,你不能重複利用這個數組中同樣的元素。
示例:
給定 nums = [2, 7, 11, 15], target = 9
因爲 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
這個題目使用c++語言有兩種解法,一種是暴力解決,另一種是使用哈希表
暴力方法–兩遍迭代
基本思想:
- 從 0 到 nums.size() 按順序依次執行
- 觀察該元素後面所有的元素中是否存在一個nums[j]元素使得nums[i]+nums[j]==targer,若存在則返回當前元素與第一個符合條件元素的序號
- 這個算法的時間複雜度爲O(n^2),效率較低
vector<int> twoSum(vector<int>& nums, int target) {
int i,j;
for(i = 0;i <nums.size(); i++){
for(j = i+1; j<nums.size(); j++ ){
if((nums[i]+nums[j])==target){
return vector<int>{i,j};
}
}
}
return vector<int>{};
}
哈希表方法
-
兩遍哈希表
- 第一遍:將元素值和索引添加到哈希表
- 第二遍:檢查當前元素對應的 target-nums[i] 是否在表中
- 時間複雜度O(n),空間複雜度O(n)
vector<int> twoSum(vector<int>& nums, int target){
map<int,int> hash;
int temp;
for(int i=0;i<nums.size();i++)
hash[nums[i]]=i;
/*
將元素值和索引以鍵值對形式添加到表中
nums[i]爲鍵,i爲值
*/
for(int i=0;i<nums.size();i++){
temp = target-nums[i];
if(hash.find(temp)!=hash.end()&&hash[t]!=i)
/*
hash.end()函數代表不存在要查找元素時返回的迭代器
要查找的元素不能是nums[i]這個元素本身
*/
return vector<int>{i,hash.find(temp)->second};
/*
first訪問鍵值對的第一個元素key,
second訪問鍵值對的第二個元素value
*/
}
}
return vector<int>();
}
-
一遍哈希表
- 這個方法在兩遍哈希表的基礎上加以改進
- 不再是完整的添加鍵值對後再遍歷,而是一遍添加鍵值對一邊遍歷
- 例如:
添加第4對鍵值對,那麼就在前3對中遍歷尋找,不存在時才加入第4對
添加第n對鍵值對,那麼就在前n-1對中遍歷尋找,不存在時才加入第n對 - 時間複雜度O(n),空間複雜度O(n)
vector<int> twoSum(vector<int>& nums, int target){
map<int,int> hash;
int temp;
for(int i=0; i<nums.size(); i++){
temp = target - nums[i];
if(hash.find(temp)!=hash.end())
return vector<int>{hash.find(temp)->second,i};
hash[nums[i]] = i;
}
return vector<int,int>{};
}