您的位置:首页 > 其它

leetcode 1. Two Sum

2016-12-24 10:45 357 查看

leetcode 1. Two Sum

Question

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.

Example

Given nums = [2, 7, 11, 15], target = 9,

Because nums[0] + nums[1] = 2 + 7 = 9,

return [0, 1].

问题

给定一个整数数组和一个目标整数,返回两个索引值,使得这两个索引对应的两个数组元素的和为目标数组。假设只有唯一解。

分析

首先想到的肯定是常规的两重遍历法,时间复杂度为O(n2);

倒排索引法(inverted index):创建一个map,把数组的value作为key,把数组的key作为value。一次遍历数组nums,通过倒排索引的map查找key为target - nums[i]的value j,则[i, j]即为所求索引对;

首尾指针夹逼法:首先将数组排序(注意要保存原索引),然后首尾两个指针分别向中间移动,直到找到符合条件的指针对。

代码

两重遍历法:

vector<int> twoSum(vector<int>& nums, int target) {
vector<int> ret;
for (int i = 0; i < nums.size(); i++)
{
for (int j = i + 1; j < nums.size(); j++)
{
if (nums[i] + nums[j] == target)
{
ret.push_back(i);
ret.push_back(j);
return ret;
}
}
}
return ret;
}


倒排索引法:

vector<int> twoSum(vector<int>& nums, int target) {
vector<int> ret;
map<int, int> numsMap;
for (int i = 0; i < nums.size(); i++)
{
if (numsMap.find(target - nums[i]) == numsMap.end())
{
numsMap[nums[i]] = i;
}
else
{
ret.push_back(numsMap[target - nums[i]]);
ret.push_back(i);
break;
}
}
return ret;
}


首尾夹逼法:

struct Compare
{
bool operator() (const pair<int, int> &lhs, const pair<int, int> &rhs)
{
return lhs.second < rhs.second;
}
};

vector<int> twoSum(vector<int>& nums, int target) {
vector<int> ret;
vector<pair<int, int>> numsPair;
for (int i = 0; i < nums.size(); i++)
{
numsPair.push_back({i, nums[i]});
}
sort(numsPair.begin(), numsPair.end(), Compare());
int beg = 0;
int end = nums.size() - 1;
while(beg < end)
{
int sum = numsPair[beg].second + numsPair[end].second;
if (sum == target)
{
ret.push_back(numsPair[beg].first);
ret.push_back(numsPair[end].first);
break;
}
else if (sum < target)
{
beg++;
}
else if (sum > target)
{
end--;
}
}
return ret;
}


复杂度再分析

网上看到很多网友说倒排索引法的时间复杂度是O(n),我觉得是不对的,应该是O(nlogn)。假设当前进行到第i次循环,numsMap中有i-1个元素,STL map的find操作是O(logn)的复杂度,那么整个循环的复杂度应该是log1 + log2 + log3 + … + log(i-1) >= (i - 1)log(i-1)。

至于首尾夹逼法,由于有排序,所以复杂度也是O(nlogn)。

总结

当需要用value来定位key的时候,需要用倒排索引;

有序序列可以用二分法、首尾指针夹逼法快速查找元素。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: