概述
今天正式开始刷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。
最后
以上就是端庄小蚂蚁为你收集整理的LeetCode Two Sum 及C++map浅显理解的全部内容,希望文章能够帮你解决LeetCode Two Sum 及C++map浅显理解所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复