题目:
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 haveexactly** one solution.
翻译:
给定一个数组和一个特定的数sum,找出数组中的两个数,使其和为sum,返回这两个数的索引。
解法一:
暴力循环
vector<int> twoSum(vector<int>& numbers, int sum) {
vector<int> res(2);
for (unsigned int i = 0; i < numbers.size(); ++i) {
for (unsigned int j = i + 1; j < numbers.size(); ++j) {
if (numbers[i] + numbers[j] == sum) {
res[0] = i;
res[1] = j;
return res;
}
}
}
return res;
}
显然,空间复杂度:O(1),时间复杂度O(n^2)
解法二:
借用hash查找时O(1)的特性,可以把时间复杂度降低到O(n),但同时也付出了空间复杂度O(n)的代价
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> res(2);
map<int, int> mp;
for (unsigned int i = 0; i < nums.size(); ++i) {
mp[nums[i]] = i;
}
for (unsigned int i = 0; i < nums.size(); ++i) {
map<int,int>::iterator it = mp.find(target - nums[i]);
if (it != mp.end() && i != mp[target-nums[i]]) {
res[0] = i;
res[1] = mp[target - nums[i]];
return res;
}
}
return res;
}
稍微优化一下:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> res(2);
map<int, int> mp;
for (unsigned int i = 0; i < nums.size(); ++i) {
map<int,int>::iterator it = mp.find(target - nums[i]);
if (it != mp.end() && i != mp[target-nums[i]]) {
if (i < mp[target - nums[i]]) {
res[0] = i;
res[1] = mp[target - nums[i]];
} else {
res[0] = mp[target - nums[i]];
res[1] = i;
}
return res;
}
mp[nums[i]] = i;
}
return res;
}
解法三:
先将数组排个序,然后利用二分查找的思想,从两头往中间逼,这样下来时间复杂度为O(nlogn) + O(n),空间复杂度,因为需要保存原始数组值与索引的对应关系,故为O(n)
bool less_cmp(pair<int, int> a, pair<int, int> b) {
return a.first < b.first;
}
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> res(2);
vector<pair<int, int> > index;
for (unsigned int i = 0; i < nums.size(); ++i) {
index.push_back(make_pair(nums[i], i));
}
sort(index.begin(), index.end(), less_cmp);
//sort()
unsigned int begin = 0;
unsigned int end = index.size() - 1;
while (begin < end) {
if (index[begin].first + index[end].first == target) {
res[0] = index[begin].second;
res[1] = index[end].second;
return res;
} else if (index[begin].first + index[end].first < target) {
++begin;
} else {
--end;
}
}
return res;
}
};