不重要:
最近天天玩吃雞,優點頹廢,好好堅持刷一下LeetCode,本博客力求一題多解,從時間複雜度上完成自我代碼修養的提高。
problem:
Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
Example:
Given nums = [2, 7, 11, 15], target = 9, Because nums[0] + nums[1] = 2 + 7 = 9, return [0, 1].
方法1:
分析:
首先我們知道:無需把數組中所有的符合要求的下標組列出來,只需要一組,並且與順序無關。我們很容易想到一種思路如下圖:
我們可以從第一個藍色開始:一個一個跟後面的比對;繼而黃色;以此類推...發現有數據對滿足和爲:target.就結束尋找;並返回兩者下標;
代碼如下:
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> answer;
int len=(int)nums.size();
for(int i=0;i<len-1;i++)
for(int j=i+1;j<len;j++)
{
if((nums[i]+nums[j])==target)
{
answer.insert(answer.end(), i);
answer.insert(answer.end(), j);
break;
}
}
return answer;
}
};
運行效果:
reference binding to null pointer of type 'value_type'注意:vector的賦值分兩個,一者在初始化的時候;一者在後續插入。由於代碼中answer的初始化未進行,所以,如果用
answer[0]=i;
answer[1]=j;
替換
answer.insert(answer.end(), i);
answer.insert(answer.end(), j);
則會出現上述錯誤;
方法2:
上述的方法雖然可以通過,但是我們不難發現,時間成本還是比較高,時間複雜度是O(N^2),顯然不是最優秀的解法,於是,上網搜索更好的思路發現了新大陸:hash_map,通過這種Key+value的快速搜索結構體,我們可以進一步加快我們的程序;
新版的C++ 11中hash_map都是unordered_map了,所以這裏只說unordered_map,但也要區分它和map的區別:
運行效率方面:unordered_map最高,而map效率較低但 提供了穩定效率和有序的序列。
佔用內存方面:map內存佔用略低,unordered_map內存佔用略高,而且是線性成比例的。
unordered_map的用法:
開頭:
#include<tr1/unordered_map>//加上tr1庫名,
using namespace std::tr1;//加上命名空間
初始化:
unorder_map<int, string> mapStudent; mapStudent[1] = “student_one”; mapStudent[2] = “student_two”; mapStudent[3] = “student_three”;
查找:若有unordered_map<int, int> mp;查找x是否在map中
方法1: 若存在 mp.find(x)!=mp.end()
方法2: 若存在 mp.count(x)!=0
插入:
map.insert(map::value_type(1,"Raoul"));
遍歷:
unordered_map<int, string>::iterator iter;map<int, string>::iterator iter;
for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)
{...}
利用Value查找Key&&刪除:
map<int, string>::iterator iter;
iter = mapStudent.find(1);
mapStudent.erase(iter);
代碼如下:
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> answer;
unordered_map<int,int> hash;
for(int i=0; i<nums.size(); i++)
{
int NumToFind=target-nums[i];
if(hash.find(NumToFind) != hash.end())
{
answer.push_back(hash[NumToFind]);
answer.push_back(i);
return answer;
break;
}
else
hash[nums[i]]=i;
}
}
};
代碼註解:
你可能覺得hash對象並沒有被初始化:這不是問題:因爲這裏比較巧妙,hash一開始確實是空的:不過在每一次循環中,最後都會執行:
hash[nums[i]]=i;
所以hash是從頭部開始進入的:比如:【2,6,9,8,3,4】target=5最後輸出的是第五層for循環中(i=4),發現NumToFind=5-3=2時候,從hash中找到了2,這樣得出來的,這也解釋了answer中爲什麼先push進去的不是i;所以這裏有點巧妙,也可以說:有點難理解,是一個“反哺”的機制,挺有意思的;
運行結果:
總結:
這樣,時間從189ms提高到了9ms,十分滿足,而且也順便學了unordered_map的用法。