1、题目描述
给定一个整数数组 nums
和一个目标值 target
,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1]
2、我的代码
我的代码,时间超了,不具有参考价值,,代码小白现在只能想出这个方法,记录一下
1、遍历两遍,找到数据
2、(nums[i]!=nums[j])&&(nums[i]+nums[j]==target)
两个数不相等,但是相加为target
3、(nums[i]==nums[j])&&(i!=j)&&(nums[i]+nums[j]==target)
两个数相等,但是不是同一个下标(数组中有两个数相等的情况),相加为target
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> res;
for(int i=0;i< nums.size();i++)
{
for(int j=i+1;j< nums.size();j++)
{
if(((nums[i]!=nums[j])&&(nums[i]+nums[j]==target))||((nums[i]==nums[j])&&(i!=j)&&(nums[i]+nums[j]==target)))
{
res.push_back(i);
}
}
}
return res;
}
};
3、正确代码
1、将数组映射到哈希表中,表中存储数据为数组数据的下标
2、假设a+b=c,比对a与b的下标(哈希表中数据),不同即输出
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> myhash;
vector<int> out;
/* 首先所有的数据哈希映射表 */
for (int i = 0; i < nums.size(); i++) {
myhash[nums[i]] = i;
}
for (int i = 0; i < nums.size(); i++) {
/* 在这里判断 如果存在 target - nums[i] 对应的值 并且这个值不是自己 */
if (myhash[target - nums[i]] && (myhash[target - nums[i]] != i)) {
out.push_back(i);
out.push_back(myhash[target - nums[i]]);
return out;
}
}
return out;
}
};
注意:
1、myhash[]中记录的是数组元素(第一个加数)的下标
2、myhash[target - nums[i]]记录的是与第一个加数相加为target 的第二个加数的下标。
以{3,3}为例:
1、当i=0时,nums[0]为3;
2、映射到哈希表中myhash[3]的值为:3在nums中的下标0,第二个3时将myhash[3]的值改为:1,即myhash[3]=1;
3、target - nums[i]=6-3=3,myhash[target -nums[i]]=myhash[3]=1;
4、myhash[target - nums[i]]=1,即存在并且值为1;第一步中i=0,明显二者不相等,所以输出i和myhash[target - nums[i]]即为{0,1}
5、当i=1时,nums[0]为3;myhash[3]=1;myhash[target -nums[i]]=1;与i相同,不符合条件。即最终输出为{0,1}
4、我的思考,改变条件
给定一个整数数组 nums
和一个目标值 target
,请你在该数组中找出和为目标值的 两个 整数 所有整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案答案不唯一 。但是,数组中同一个元素不能使用两遍。
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> myhash;
vector<int> out;
/* 首先所有的数据哈希映射表 */
for (int i = 0; i < nums.size(); i++) {
myhash[nums[i]] = i;
}
for (int i = 0; i < nums.size(); i++) {
/* 在这里判断 如果存在 target - nums[i] 对应的值 并且这个值不是自己 */
if (myhash[target - nums[i]] && (myhash[target - nums[i]] != i)) {
out.push_back(i);
out.push_back(myhash[target - nums[i]]);
//return out;//不止一对
//一对加数,前面输出,后面不再输出
//myhash[i]=0;//使其不满足条件一
myhash[i]=myhash[target - nums[i]];//使其不满足条件二
}
}
return out;
}
};
1、假设nums[]={3,3,2,4,5};target=6;
2、映射到哈希表中,myhash[]中记录的是数组元素(第一个加数)的下标
myhash[nums[0]] =myhash[3] = 0;
myhash[nums[1]] =myhash[3] = 1;//myhash[3] 中的0被覆盖掉
myhash[nums[2]] =myhash[2] = 2;
myhash[nums[3]] =myhash[4] = 3;
myhash[nums[4]] =myhash[5] = 4;
3、找到与第一个加数相加为target 的第二个加数的下标
myhash[target - nums[0]] = myhash[3] = 1;
myhash[target - nums[1]] = myhash[3] = 1;
myhash[target - nums[2]] = myhash[4] = 3;
myhash[target - nums[3]] = myhash[2] = 2;
myhash[target - nums[4]] = myhash[1] = null;
4、做判断
myhash[target - nums[i]]
存在,哈希表中存在与数组中第一个加数相加为target的 第二个加数的下标,即第二个加数存在;myhash[target - nums[i]] != i
第二个加数存在后,还要确保他的下标与第一个加数的下标不相同,即满足数组中同一个元素不能使用两遍;
5、输出
myhash[target - nums[0]] = myhash[3] = 1;i=0
myhash[target - nums[1]] = myhash[3] = 1;i=1(不满足条件)
myhash[target - nums[2]] = myhash[4] = 3;i=2
myhash[target - nums[3]] = myhash[2] = 2;i=3
myhash[target - nums[4]] = myhash[1] = null;(不满足条件)
1、按照以前思路输出就是{0,1}
2、注释掉if语句中的return out;
输出就是{0,1,2,3,3,2}那么怎么解决重复问题呢
3、首先满足两个条件的才会被输出,如果前面已经输出了{2,3},那么{3,2}必然也满足条件,那么想办法让他不满足就可以了。我们核心思想是在数组中找一对数,相加为target,第二个加数存在后判断它与对应的第一个加数两个下标是否不同。
- 条件1:i对应的
myhash[target - nums[i]]
存在,即i为第一个加数时,第二个加数myhash[target - nums[i]]
存在。反之当i=第二个加数作时,第一个加数就成为了第二个加数,必然存在的。那么我可以在这对加数第一次输出后,将第一个加数i在哈希表中的值置为0(myhash[i]=0;
),那么当第二个加数作为i出现时,找到它对应的myhash[target - nums[i]]
就是不存在的,不满足条件不会输出。 - 条件2:i对应的
myhash[target - nums[i]]!=i;
那么我可以在这对加数第一次输出后,将第一个加数i在哈希表中的值置为其对应的第二个加数在哈希表中的值(myhash[i]=myhash[target - nums[i]];
),那么当i=第二个加数作时,找到它对应的myhash[target - nums[i]]
就是与自己也就是i相等的,不满足条件不会输出。