1. Two Sum
Given an arrayof integers, return indices of the two numbers such that theyadd up to a specific target.
You may assumethat each input would have exactly one solution.
Example:
Given nums = [2, 7,11, 15], target = 9,
Because nums[0]+ nums[1] = 2 + 7 = 9,
return [0, 1].
UPDATE (2016/2/13):
The return format had been changed to zero-based indices.Please read the above updated description carefully.
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
}
};
解题思路:
自己的解题思路
首先,将nums进行排序O(nlgn);然后,从首位两端进行搜索,直到查找目标O(n);
主要复杂度在排序上面。
注意点,因为排序之后,序号会发生改变,所以必须继续记录index;因此加入一个辅助数组vector<Node> n_vec;
别人的解题思路
通过使用unordered_map的find()成员函数,实现快速查找。其中key是值,value是序号。
键值允许重复,当然也可以通过优化实现map查找。
学习收获:
unordered_map存在reserve(),但是map不存在reserve()成员函数。
熟悉(unordered_)map.find()的使用,返回迭代器。Eg:
valueIndices.find(value) != valueIndices.end() //如果不相等,就是找到;或者返回end()
附件1:程序
1、自己的程序:
class Solution
{
public:
vector<int> twoSum(vector<int>&nums,int target)
{
struct Node
{
int index;
int num;
};
vector<Node> n_vec;
for(int i=0;i!=nums.size();++i)
{
n_vec.push_back(Node{i,*(nums.begin()+i)});
}
sort(n_vec.begin(),n_vec.end(),[](Nodelh,Noderh){returnlh.num<rh.num;});
int i=0,j=static_cast<int>(nums.size()-1);
while(i<j)
{
int temp=(n_vec.begin()+i)->num+(n_vec.begin()+j)->num;
if(temp<target)
{
++i;
}
else if(temp>target)
{
--j;
}
else
{
break;
}
}
if(i<j)
{
vector<int> a{(n_vec.begin()+i)->index,(n_vec.begin()+j)->index};
returna;
}
return vector<int>();
}
};
2、别人的程序
vector<int> twoSum(vector<int>& numbers,int target)
{
//Key is the number and value is its index in the vector.
unordered_map<int,int> hash;
vector<int> result;
for(int i=0;i<numbers.size();i++)
{
int numberToFind=target-numbers[i];
//if numberToFind is found in map, return them
if(hash.find(numberToFind)!=hash.end())
{
//+1 because indices are NOT zero based
result.push_back(hash[numberToFind]+1);
result.push_back(i+1);
return result;
}
//number was not found. Put it in the map.
hash[numbers[i]]=i;
}
return result;
}
点评:
存在几个bug。首先,序号没有按照题目给的约定来;其次,出现重复序列的话,会出现问题。
Error Case:
target = 11,items = [2 4 4 7 10]
Output: [3,4] ExpectedAnswer: [2, 4]
改进的程序:
在将值push到unordered_map时,对于重复的值,只需要push1次。
如果答案是两个重复的值,那么在考虑push之前,他们已经被输出,而且是正确输出。
vector<int> twoSum(vector<int>& nums,int target)
{
vector<int> result(2);
unordered_map<int,int> valueIndices;
valueIndices.reserve(nums.size()*2); //this isbuckets, not bytes
for(size_t i=0;i!=nums.size();++i)
{
int value=target-nums[i];
if(valueIndices.find(value)!=valueIndices.end())
{
result[0]=valueIndices[value]+1;
result[1]=i+1;
break;
}
else
{
//This makes sure that return the first item's indexamong duplicate elements
if(valueIndices.find(nums[i])==valueIndices.end())
{
valueIndices[nums[i]]=i;
}
}
}
return result;
}
附件2:扩展阅读(简单看一下就好,转载)
原文出处:https://leetcode.com/articles/two-pointer-technique/