描述
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.
你可以假定每一组输入只有唯一解, 相同元素最好不要使用2次以上
Example:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
解决方案
暴力法
最简单直观, 循环每个元素x, 看另一个元素是否等于target-x. 相等的化返回对应下标
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> result;
for (int i=0; i < nums.size(); i++) {
for (int j=i+1; j < nums.size(); j++) {
if (nums[j] == (target - nums[i])) {
result.push_back(i);
result.push_back(j);
j = nums.size();
i = j;
}
}
}
return result;
}
};
复杂度分析
时间复杂度: 对每个元素, 都要循环余下的元素, 因此复杂度为
O
(
n
2
)
O(n^2)
O(n2)
空间复杂度:
O
(
1
)
O(1)
O(1)
哈希表
思路: 需要一种快速的方式来判断target-x是否存在, 然后根据这个值来确定下标.
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
map<int, int> map;
vector<int> result;
for (int i=0; i < nums.size(); i++) {
//map.insert(pair<int, int>(nums[i], i));
map[nums[i]] = i;
}
for (int i=0; i < nums.size(); i++) {
int complement = target - nums[i];
if (map.find(complement) != map.end() && map[complement] != i) {
result.push_back(i);
result.push_back(map[complement]);
break;
}
}
return result;
}
};
复杂度分析
时间复杂度: 对每个元素遍历了2次, 查询时间只有
O
(
1
)
O(1)
O(1), 所以总的复杂度是
O
(
n
)
O(n)
O(n),
空间复杂度: hashmap的大小和输入时一样的, 因此为
O
(
n
)
O(n)
O(n)
一轮哈希表
上个方法我们对数组的每个元素使用了2次, 其实可以减为一次的
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
map<int, int> map;
vector<int> result;
for (int i=0; i < nums.size(); i++) {
map[nums[i]] = i;
int complement = target - nums[i];
if (map.find(complement) != map.end() && map[complement] != i) {
result.push_back(i);
result.push_back(map[complement]);
break;
}
}
return result;
}
};
复杂度分析
时间复杂度: 对每个元素遍历了1次, 查询时间只有
O
(
1
)
O(1)
O(1), 所以总的复杂度是
O
(
n
)
O(n)
O(n),
空间复杂度: hashmap的大小和输入时一样的, 因此为
O
(
n
)
O(n)
O(n)
排序法
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> result;
vector<int> ns = nums;
sort(ns.begin(), ns.end());
int a = 0, b = nums.size() - 1;
while (a < b) {
if ((ns[a] + ns[b]) > target) --b;
else if ((ns[a] + ns[b]) < target) ++a;
else break;
}
if (a < b) {
for (int i = 0; i < nums.size(); ++i) {
if (nums[i] == ns[a] || nums[i] == ns[b]) {
result.push_back(i);
}
}
if (result[0] > result[1]) {
swap(result[0], result[1]);
}
}
return result;
}
};
复杂度分析
时间复杂度: 对元素拷贝
O
(
n
)
O(n)
O(n), 排序
O
(
n
∗
l
o
g
(
n
)
)
O(n*log(n))
O(n∗log(n)), 查询
O
(
n
)
O(n)
O(n), 所以最后为
O
(
n
∗
l
o
g
(
n
)
)
O(n*log(n))
O(n∗log(n))
空间复杂度:
O
(
n
)
O(n)
O(n)