1. 两数之和
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
C++
- 暴力解法
两层for循环
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
int i,j;
for(int i=0;i<nums.size()-1;i++){
for(int j=i+1;j<nums.size();j++){
if(nums[i]+nums[j] == target)
return {i,j};
}
return {i,j};
}
};
注意:leecode的编译器要求不管最后的return能不能用上都必须return,及时前面return返回过后面也要再返回一次。
- 两遍哈希
用map实现,map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据处理能力
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int,int> m;
for(int i=0;i<nums.size();i++)
m[nums[i]] = i; //向map中添加元素
for(int i=0;i<nums.size();i++)
{
if(m.find(target-nums[i]) != m.end() && m[target-nums[i]] != i) //如果m中存在对应的键值,并且不为i
return {i , m[target-nums[i]]};
}
return {i,j};
}
};
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
map<int,int> a;//建立hash表存放数组元素
vector<int> b(2,-1);//存放结果
for(int i=0;i<nums.size();i++)
a.insert(map<int,int>::value_type(nums[i],i));
for(int i=0;i<nums.size();i++)
{
if(a.count(target-nums[i])>0&&(a[target-nums[i]]!=i))
//判断是否找到目标元素且目标元素不能是本身
{
b[0]=i;
b[1]=a[target-nums[i]];
break;
}
}
return b;
};
};
- 一遍哈希
在进行迭代并将元素插入到表中的同时,我们还会回过头来检查表中是否已经存在当前元素所对应的目标元素。如果它存在,那我们已经找到了对应解,并立即将其返回。
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int,int> m;
for(int i=0;i<nums.size();i++)
{
if(m.find(target-nums[i]) != m.end()) //m中存在对应的键值
return {m[target-nums[i]] , i}; //m[target-nums[i]]为已经加入map的元素的索引,所以小于本轮循环中的i,放在前面
m[nums[i]]=i; //向map中添加元素
}
return {i,j};
}
};
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
map<int,int> a;//提供一对一的hash
vector<int> b(2,-1);//用来承载结果,初始化一个大小为2,值为-1的容器b
for(int i=0;i<nums.size();i++)
{
if(a.count(target-nums[i])>0)
{
b[0]=a[target-nums[i]];
b[1]=i;
break;
}
a[nums[i]]=i;//反过来放入map中,用来获取结果下标
}
return b;
};
};