LeetCode Two Sum 及C++map淺顯理解
阿新 • • 發佈:2018-11-08
今天正式開始刷LeetCode,發現上面和其它地方的oj真的不太一樣。首先,最最最好的一點就是你可以在上面線上敲程式碼然後執行,不用自己再開啟vs或者dev,然後就是,它不讓你關心資料到底是如何輸入輸出的,唯一關心的就是你的核心程式碼,就是說只要主體結構正確,你不用考慮輸入輸出(這個簡直太良心了,其它OJ好多題都是死在輸入輸出上有木有!),完成solution這個函式(或者類,在C++下)就行。
好了,我們來看下第一道題,Two Sum,意思是給你一個整型的陣列,讓你找出其中兩個數加起來可以相等於target的數的下標。第一眼看到這個題的時候,就想,這還不簡單,不就兩個for迴圈嗎,簡單
for (int i=0; i<numbers.size(); ++i)
{
for (int j=i+1; j<numbers.size(); ++j)
{
if (numbers[i] + numbers[j] == target)
{
a = i;
b = j;
break;
}
}
}
然後,就TLE了,說明不能這麼簡單的去做。後來又試了另外一種做法,就是新建個類,類中儲存陣列的值及對應的下標位置,然後對這些類組成的vector進行從小到大排序,額,還是看程式碼吧
class Node{
public:
int value;//用來儲存陣列的值
int key; //用來儲存對應值所對應的下標
};
bool cmp(Node a, Node b)
{
return a.value < b.value; //排序函式所需謂詞,從小到大進行排序
}
class Solution {
public:
vector<int> twoSum(vector<int> &numbers, int target) {
int i, sum;
vector<int > results; //用來儲存結果
vector<Node> arry;
for (i=0; i<numbers.size(); ++i) //這一步就是將陣列numbers所有的值及相對應的下標存進去
{
Node *tmp = new Node;
tmp->value = numbers[i];
tmp->key = i+1;
arry.push_back(*tmp);
}
sort(arry.begin(),arry.end(),cmp); //對arry按照值的大小從小到大進行排序
vector<Node>::iterator j = arry.begin();
vector<Node>::iterator k = arry.end()-1;
sum = 0;
/*
這一部分很簡單,其實就是對已經排序好的arry從兩頭開始
進行查詢,若sum小於target,很明顯需要將j往後移位,若sum
大於target,很明顯需要將k往前移位,直到找到sum==target
*/
while (j < k)
{
sum = j->value + k->value;
if (sum > target) --k;
else if (sum < target) ++j;
else
{
int temp;
if (j->key > k->key)//考慮到陣列中有負數的原因,會因為排序後而發生j->key > k->key 的現象,需要調換
{
temp = j->key;
j->key = k->key;
k->key = temp;
}
results.push_back(j->key);
results.push_back(k->key);
break;
}
}
return results;
}
};
這個過了,時間複雜度最大也就sort函式吧,大概O(nlgn),比O(n2)好多了。
還有看見discuss裡面有大神用c++的map來做,確實簡單多了,貼程式碼如下:
class Solution {
public:
vector<int> twoSum(vector<int> &numbers, int target) {
int i, sum;
vector<int> results;
map<int, int> hmap;
for(i=0; i<numbers.size(); i++){
if(!hmap.count(numbers[i])){
hmap.insert(pair<int, int>(numbers[i], i));
}
if(hmap.count(target-numbers[i])){
int n=hmap[target-numbers[i]];
if(n<i){
results.push_back(n+1);
results.push_back(i+1);
return results;
}
}
}
return results;
}
};
map是c++裡面的一種關聯容器,其原型是map
if(!hmap.count(numbers[i])){
hmap.insert(pair<int, int>(numbers[i], i));
}
意思就是如果numbers[i]在map中沒有出現過,就將(numbers[i],i)插入到map中,其中numbers[i]相當於key,i相當於value。因為map中的查詢是很快的,所以時間複雜度很低。
另外,map要求其中的key值不允許重複,即一個key只對應一個value。