题目描述:
给定一个整数数组 nums
和一个目标值 target
,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
示例:
给定 nums = [2, 7, 11, 15], target = 9 因为 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1]
思路:
假定 nums[ i ] + nums [ j ] = target ,则 nums [ j ] = target - nums[ i ] ;
也就说,我们只要在以nums[ i ]为基准下,遍历数组找到 一个等于 target - nums[ i ] 的元素即可。
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> v;
for(int i= 0;i<nums.size();i++){
int n = target-nums[i];
for(int j = i+1;j<nums.size();j++){
if(nums[j]==n){
v.push_back(j);
v.push_back(i);
return v;
}
}
}
return v;
}
};
运行结果:
耗时过长的原因是在遍历 vector 容器时查找元素的速度不理想,最坏情况下的时间为 O(n);
那么,我们可以使用查找效率比较高的二叉树 map 容器来完成查找的工作。
map 容器的元素具有两个值:键值,实值 。
其中键值不可重复。
思路:
- 利用 map 的键值来存放每一个 target - nums[i] ,用实值存放下标。
- 在每次存放元素 nums[ i ]之前,查找容器中是否存在满足 target - nums[i] 的值。
- 如果满足,则将 键值和实值存入新的 vector 中;
- 否则重复 1 的步骤。
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> result;
map<int, int> table;
for (int i = 0; i < nums.size(); ++i) {
int complement = target - nums[i];
if (table.find(complement) != table.end()) {
result.push_back(table[complement]);
result.push_back(i);
} else {
table[nums[i]] = i;
}
}
return result;
}
};
运行结果: