Description:
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].
描述:
给定一个整数数组,返回数组中两个数字的索引,使得这两个数字的和为给定的目标值。
假设每个输入数组只有一个解,并且数组中每个元素只使用一次。
示例:
给定的数组 nums = [2, 7, 11, 15], 目标值为 9, 因为nums[0] + nums[1] = 2 + 7 = 9, 返回值为:[0, 1].
方法1:暴力搜索
思路:遍历数组中任意两个元素,并计算两个元素的和,如果两个元素的和等于给定的目标值,则返回两个元素的索引。
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> res;
if(nums.size() < 2) {
return res;
}
for(int i = 0; i < nums.size() - 1; i++) {
for(int j = i + 1; j < nums.size(); j++) {
if(nums[i] + nums[j] == target) {
res.push_back(i);
res.push_back(j);
break;
}
}
}
return res;
}
};
本方法包含两层循环,时间复杂度为Ο(n2),空间复杂度为O(1).
方法二:
分析方法一,发现其包含两层循环,一种直观的想法是降低循环的层数。为此,本方法首先遍历一遍数组,采用map结构保存数组中每个元素和其对应索引值。
接着,再次遍历数组,判断数组元素值val和该元素对应的目标值的补值(即target - val)是否在map结构中。如果存在,则返回这两个元素的索引值。
本方法将方法一中的两层循环遍历,更改为两次对数组的遍历,降低了时间复杂度。
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
map<int, int> val2Idx;
vector<int> res;
for(int i = 0; i < nums.size(); i++) {
val2Idx.insert(make_pair(nums[i], i));
}
for(int i = 0; i < nums.size(); i++) {
int val = target - nums[i];
if(val2Idx.find(val) != val2Idx.end() && val2Idx[val] != i) {
int idx = val2Idx[val];
int idx2 = i;
if(idx < idx2) {
res.push_back(idx);
res.push_back(idx2);
} else {
res.push_back(idx2);
res.push_back(idx);
}
break;
}
}
return res;
}
};
本方法的时间复杂度为O(n),空间复杂度为O(n)。
方法三:
方法二通过遍历数组构建元素值和相应索引的map结构。因此,需要遍历数组两次。本方法通过将构建map结构和数组遍历放在同一个素组遍历过程中,优化程序。
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
map<int, int> val2Idx;
vector<int> res;
for(int i = 0; i < nums.size(); i++) {
val2Idx.insert(make_pair(nums[i], i));
int val = target - nums[i];
if(val2Idx.find(val) != val2Idx.end() && val2Idx[val] != i) {
int idx = val2Idx[val];
int idx2 = i;
if(idx < idx2) {
res.push_back(idx);
res.push_back(idx2);
} else {
res.push_back(idx2);
res.push_back(idx);
}
break;
}
}
return res;
}
};
本方法的时间复杂度为O(n),空间复杂度为O(n)。