从数组中找到两个数字和等于目标值的一对数字,返回它们在数组中的下标。
难度 【easy】
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].
下面我使用四种方法进行解决:
目录
方法一:暴力求解法
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 (target - nums[i] == nums[j]) {
result.push_back(i);
result.push_back(j);
break;
}
}
}
return result;
}
};
时间复杂度:O(n^2)
空间复杂度:O(1)
方法二:利用哈希表存放数组中所有元素
下面要注意的是不能两个元素相同,在命中hash时,需要判断命中的元素的下标是否等于第一个元素的下标,如果相等,那么就需要继续查找了。
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> result;
unordered_map<int, int> hashmap1;
for (int i = 0; i < nums.size(); ++i) {
hashmap1[nums[i]] = i;
}
for (int i = 0; i < nums.size(); ++i) {
int a = target - nums[i];
if (hashmap1.count(a) > 0 && hashmap1[a] != i) {
result.push_back(i);
result.push_back(hashmap1[a]);
break;
}
}
return result;
}
};
时间复杂度:O(n)
空间复杂度:O(n)
方法三:利用哈希表存放一部分元素
此种方法比较巧妙,一般不是特别容易想到,是对方法二的优化,能够节省部分空间。
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> result;
unordered_map<int, int> hashmap1;
for (int i = 0; i < nums.size(); ++i) {
int a = target - nums[i];
if (hashmap1.count(a) > 0) {
result.push_back(i);
result.push_back(hashmap1[a]);
break;
} else {
hashmap1[nums[i]] = i;
}
}
return result;
}
};
时间复杂度:O(n)
空间复杂度:O(n)
方法四:利用辅助数组,对数据进行排序
使用两个指针(数组下标),一个指向head,一个指向rear,每次循环都对这两个指针指向的元素相加,如果sum大于target,那么尾部指针向前移动;如果sum小于target,那么头部指针向后移动。
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> result;
int n = nums.size();
vector<pair<int, int> > tmp(n);
for (int i = 0; i < n; ++i) {
tmp[i] = make_pair(nums[i], i);
}
sort(tmp.begin(), tmp.end());
int i = 0;
int j = n - 1;
while (i < j) {
int two_sum = tmp[i].first + tmp[j].first;
if (two_sum == target) {
result.push_back(tmp[i].second);
result.push_back(tmp[j].second);
break;
} else if (two_sum > target) {
--j;
} else {
++i;
}
}
return result;
}
};
时间复杂度:O(n)
空间复杂度:O(n)
四种方法leetcode的耗时和空间占用情况
方法 | Runtime | Memory |
1 | 168 ms | 9.5 MB |
2 | 12 ms | 10.5 MB |
3 | 12 ms | 10.2 MB |
4 | 8 ms | 9.7 MB |