1. 两数之和
题目描述
给定一个整数数组 nums
和一个目标值 target
,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
样例
输入:
nums
= [2, 7, 11, 15],target
= 9输出:
[0, 1]
解释 :
因为 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1]
算法 - 哈希表($O( n)$)
思路
- 利用哈希表保存每个值对应的下标
- 遍历数组的过程中
- 判断
target - nums[i]
是否存在于哈哈希表中 - 更新哈希表,将
nums[i]
插入
- 判断
复杂度
- 时间 : $O(n)$
- 线性扫描一次且哈希表插入查询都为$O(1)$,故为$O(n)$
- 空间 : $O(n)$
- 需要额外 $O(n)$ 的空间来存每个值对应的下标
c++ 代码
leetcode
版本
vector<int> twoSum(vector<int> &nums, int target)
{
if(! nums.size()) return vector<int>();
vector<int> res;
unordered_map<int, int> hash;
for(int i=0; i<nums.size(); i++){
int temp = target - nums[i];
if(hash.find(temp) != hash.end())
{
res = vector<int> {hash[temp],i};
break;
}
hash[nums[i]]=i;
}
return res;
}
本地
版本
#include <cstdio>
#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;
vector<int> nums;
int target;
vector<int> twoSum(vector<int> &nums, int target)
{
if(! nums.size()) return vector<int>();
vector<int> res;
unordered_map<int, int> hash;
for(int i=0; i<nums.size(); i++){
int temp = target - nums[i];
if(hash.find(temp) != hash.end())
{
res = vector<int> {hash[temp],i};
break;
}
hash[nums[i]]=i;
}
return res;
}
int main()
{
int n;
cin >> n >> target;
nums = vector<int>(n);
for(int i = 0 ;i < n; i++)
cin >> nums[i];
vector<int> res = twoSum(nums, target);
cout << "index is :" ;
for(auto v : res)
cout << v << " " ;
cout << endl;
return 0;
}
小结与思考
哈希表的应用
- 存每个元素出现的
位置
,如本题 - 存每个元素出现的
次数
, 如最长不重复子串
- 存每个元素距离目标值的
差距
,如最小覆盖子串
哈希表的操作
- 该元素存在:
hash.find(x) != hash.end()
orhash.count(x)
哈希表是个好东西(窃笑)
哈希哈希,嘻嘻哈哈~~