Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
Example:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
题目解释:在一个数组中找寻两个数字的和等于目标值,返回两个数字的索引值,并且有且只有一组解,同一个位置的元素不能用两次
我的错误做法,写出来让自己注意,读者可以忽视
先排序然后使用two pointer的方式去做,会导致index乱了,返回自然会错
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> res;
sort(nums.begin(), nums.end());
int l = 0, r = nums.size() - 1;
while(l < r){
if(nums[l] + nums[r] == target){
res.push_back(l);
res.push_back(r);
return res;
}else if(nums[l] + nums[r] < target){
++l;
}else{
--r;
}
}
return res;
}
};
这道题直观的做法是O(n^2)的复杂度,二层循环暴力的将每两个数求和,得到结果与target对比。或者外层循环遍历每个数,内层循环找另外一个数。
我仔细想了很久都没有想到怎么优化。后来看了解答,可以优化内层循环找另外一个数,从复杂度为O(n)变为O(1),只用hash即可,key是数组的值,value是index,这样就把总的复杂度降为O(n)。
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> res;
unordered_map<int, int> m;
for(int i = 0; i < nums.size(); ++i){
m[nums[i]] = i;
}
for(int i = 0; i < nums.size(); ++i){
//m[target - nums[i]] != i 这是个边界条件,需要注意,嘿嘿,你不加这个条件,submission一下就懂我的意思了
if(m[target - nums[i]] != 0 && m[target - nums[i]] != i){
res.push_back(i);
res.push_back(m[target - nums[i]]);
return res;
}
}
return res;
}
};
关键trick:使用hash将遍历的复杂度从O(n)降为O(1)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。