LeetCode 1: 两数之和
题目描述
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
【示例】
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
解题
哈希表
遍历整个数组,如果当前元素与哈希表中的所有元素的和都不等于target,那么把这个元素存进哈希表中。那么如何判断当前元素与哈希表中的所有元素的和都不等于target呢?我们只需要在哈希表中查找target减去当前元素的值即可。
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> val_index;
auto iter = val_index.begin();
for (int i=0; i<nums.size(); ++i){
iter = val_index.find(target-nums[i]);
if (iter != val_index.end())
return {iter->second, i};
else
val_index[nums[i]] = i;
}
return {};
}
};
排序
如果数组是排序好的,那么可以利用双指针来寻找和为target的两个元素的位置。但是如果直接对原数组排序的话,返回的索引很可能就不再是原来的索引了,所以对原数组的拷贝进行排序,找到和为target的两个值,再从原数组中找到真正的索引。
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> nums_copy(nums.begin(), nums.end()); //拷贝
sort(nums_copy.begin(), nums_copy.end()); //排序
//寻找和为target的指针(排序后)
int i=0, j = nums.size()-1;
while (i < j){
if (j >=0 && nums_copy[i]+nums_copy[j] > target)
--j;
else if (i < nums.size() && nums_copy[i]+nums_copy[j] < target)
++i;
else
break;
}
//在原数组中寻找真实的索引
vector<int> vect;
for (int k=0; k < nums.size(); ++k){
if (i < nums.size() && nums[k]==nums_copy[i]){
vect.emplace_back(k);
i = nums.size(); //防止相同元素一直插入
}
else if (j < nums.size() && nums[k]==nums_copy[j]){
vect.emplace_back(k);
j = nums.size();
}
else if (i==j)
break;
}
return vect;
}
};