基本思想
最开始的思路是,先对numbers数组进行排序,然后用连个索引 i 和 j 分别指向排序后的数组的头尾,再根据 numbers[i]+numbers[j]与target的大小,来判断是 i++还是j–。然而这种方法求出来的索引,是排序后的数组索引,与原始数组的索引是不同的(排序破坏了位置),因此这种方法求出来的位置信息不对。当然,有想过通过保存排序后的数在原始数组中的位置来解决问题,但是,细细一想,太过于繁琐,果断放弃了。下面的代码是针对有序数组,敲出来的代码(如果没有兴趣,可以直接略过这段代码~)
vector<int> twoSum(vector<int>& numbers, int target) {
// write code here
//先对数组排序
sort(numbers.begin(),numbers.end());
//用两个索引i,j分别从排序后的数组头尾开始遍历
int i=0,j=numbers.size()-1;
vector<int> res;
// numbers[i]+numbers[j]<target,说明数太小,i++;numbers[i]+numbers[j]>target,说明数太大,j--;numbers[i]+numbers[j]==target 结束返回
while((numbers[i]+numbers[j])!=target){
if(numbers[i]+numbers[j]<target) i++;
else j--;
}
res.push_back(i+1);
res.push_back(j+1);
return res;
}
那面对无序的数组numbers,我们该怎样解决问题呢?一看leetcode的解题思路,恩,大神果然是大神,我怎么就没有想到呢?用map就可以轻松解决,当然,在此之前,要了解map的相关知识,我决定这个博主写得比较好,推个大家: https://blog.csdn.net/u010029439/article/details/89681773.
解题思路:
- 使用map来存储numbers[i]和该数在数组中的位置 i+1。
- 遍历数组,每次判断当前数target-numbers[i]差值是不是在map中,如果在,说明找到了,直接结束遍历,返回map中找到的那个数的位置,和当前数numbers[i]的位置 i+1;如果不在,则将当前数和其位置一起存入到map中,这里以array的方式插入map中。
注意:本题目中,
(1)map是这样存数据的:每一个Map元素,key-value:numbers[i]-(i+1);map的查找函数find(),查找的是关键字key,返回的是找到的关键字所在的map上的位置pos。我们要返回的是找到的关键字Key所对应的value值。因此,我们通过判断pos是不是等于map的结束位置,来判断是否找到target-numbers[i]这个关键字,如果找到,那么该关键字对应的值value为map[target-numbers[i]],即该数target-numbers[i]在原始数组中的位置。
(2)还有人会想,以array的方式插入map,如果原来有一样的数,是不是会覆盖原来的数。这个其实没有关系,因为,题目中提到,存在唯一解。
代码
//使用map來做
vector<int> twoSum(vector<int>& numbers, int target) {
//定义 一个map,用于存放numbers[i]的值以及该数在第一个位置
map<int,int> mp;
vector<int> res;
for(int i=0;i<numbers.size();i++){
if(mp.find(target-numbers[i])!=mp.end()){
res.push_back(mp[target-numbers[i]]);
res.push_back(i+1);
}
else mp[numbers[i]]=i+1;
}
return res;
}
总结
通过排序后再求解,返回的索引位置其实是新数组的位置,如果不加以处理,与原始数组所在的位置不一样,因此这种做法不行。利用Map来做,就一目了然了。每次map中存放的数是target-numbers[i]的差值,我们只需判断当前数numbers[i]是不是对应的另一个加数是不是在map中即可。
版权声明:本文为qq_42211773原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。