给定一个整数数组 nums
和一个整数目标值 target
,请你在该数组中找出 和为目标值 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 <= 104
-109 <= nums[i] <= 109
-109 <= target <= 109
- 只会存在一个有效答案
#1暴力解
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* twoSum(int* nums, int numsSize, int target, int* returnSize) {
int i=0,j=0;
for(i=0;i<numsSize;i++){
for(j=i+1;j<numsSize;j++){
if(nums[i]+nums[j]==target){//find it
//开辟空间存储
int *ret=malloc(sizeof(int)*2);
ret[0]=i;
ret[1]=j;
*returnSize=2;
return ret;
}
}
}
*returnSize=0;
return NULL;
}
进阶:你可以想出一个时间复杂度小于 O(n2)
的算法吗?
由于题目说数组中a+b的和是target,说明当前已知的任意值a,和target,另一个数必然为target-a,即b=target-a。因此我们只需要判断数组中是否有b就能够找到目标答案。在这里将所有数组存入哈希表中,nums中的元素值作为哈希表中的索引,nums中的索引作为哈希表中元素值。此时对数组进行二次遍历,并算出b,使用哈希表判断nums中是否有b,有则查找成功,否则继续往下找(有缺陷)。
PS:使用哈希表的原因:哈希表时间复杂度为1,能够快速判断nums中是否有某个元素,而使用数组每查找一次b的存在与否都需要遍历一遍nums.
查找表常用的有:哈希表(无序)和平衡二叉搜索树(有序)
#错误代码
#错因,没有对元素出现的次数做限定,若数组中只有一个值3,但是target=6,该代码会因为nums中有3而将之视为正确答案。
#include<algorithm>
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
map<int,int>ha;
for(int i=0;i<nums.size();i++){
int flag=i;
int value=nums[i];
ha[value]=flag;//哈希表和nums数组的下标和值位置对调,实现快速查找值
}
for(int i=0;i<nums.size();i++){
int b=target-nums[i];
auto it=ha.find(b); //返回的是一个迭代器,auto 关键字让编译器自动推导变量的类型,所以it 的类型将会是 map<int,int>::iterator
if(it !=ha.end()){
int j=it->second; //it->second 用于获取键为 b 的元素的值
return {i,j};
}
}
return {};
}
};
为解决上诉代码中的问题,此处选择将值存入哈希表的同时进行判断:由于要实现a+b=target需要保证a,b同时出现,因此在遇到第一个数a时可以先将a和a的数组下标存入哈希表,当遇到b时判断哈希表中有没有所需要的b,有则查找成功,没有则将b存入哈希表,继续往下遍历数组
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
map<int,int>table;
int a,b;
for(int i=0;i<nums.size();i++){
int need=target-nums[i];
if(table.find(need) != table.end() ){//哈希表中存在需要的数值,说明查找成功
a=i;
b=table[need];
return {a,b};
}
table[nums[i]]=i;
}
return {};
}
};
盲点: | 解决 |
对c,c++返回形式不清楚 | |
队列,哈希表,vector容器的值插入和应用区别 | |
哈希表中判断某个键t是否存在 | 不能用table[t]!=NULL,应该使用table.find(need) != table.end() |