twosum想必大家都是耳熟能详了!Leetcode的第一题,当时第一次刷差点劝退我!hah
废话不多说了!
题目描述:
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
你可以按任意顺序返回答案。
示例 1:
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
示例 2:
输入:nums = [3,2,4], target = 6
输出:[1,2]
示例 3:
输入:nums = [3,3], target = 6
输出:[0,1]
提示:
2 <= nums.length <= 103
-109 <= nums[i] <= 109
-109 <= target <= 109
只会存在一个有效答案
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/two-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
其实这题很多思路:
我们其实可以使用双指针,但是题目要求返回下标,双指针在边界问题的处理上会很不方便!大概题目本意就是想要我们学会map!
关于map解法:
第一种
- 我开始想的是,把所有的数组值以及下标都存储起来,然后找每个值的target - nums[i] 并且下标不相等的情况。因为我们可能会遇到这种情况!(相同的值不同的下标)
[3,3]
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
map<int,int> show;
vector<int> res;
int n = nums.size();
// 存入数据
for(int i=0;i<n;i++){
show[nums[i]] = i;
}
int val;
// 遍历数据
for(int i=0;i<n;i++){
// 找到val
val = target-nums[i];
// 其实这里最好用show.count(val),因为show[val]的值可能为0。
if(show[val]&&show[val]!=i){
res.push_back(i);
res.push_back(show[val]);
return res;
}
}
return res;
}
};
第二种
- 我在写其他题的时候,突然有这种处理办法,就是一边存一边遍历(我们就可以避免了,当 [3,3] 这种情况我们会返回自己!
- 当然这样的代码也会快一点!但返回的时候注意,需要对res排序。
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
map<int,int> show;
vector<int> res;
int n = nums.size();
int val;
for(int i=0;i<n;i++){
val = target-nums[i];
// 需要使用count,因为show[val]可能为0
if(show.count(val)){
res.push_back(i);
res.push_back(show[val]);
sort(res.begin(),res.end());
return res;
}
show[nums[i]] = i;
}
return res;
}
};
值得注意的是!这里第一种代码,我使用的是show[val](这个是我提交成功后修改的,我想稍微做点优化,因为我觉得show.count(val)会比较慢,效果不明显),但是这个值可能为0,那么我们的if就会为假,显然是不对的!所以大家还是使用count比较好!
关于双指针,大家可以学习一下就是先将数组排序,然后两个指针在两头!if相加的值比较小就left++,反之right–