题目难度: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].
暴力法(Brute Force)
时间复杂度:O(n^2)
空间复杂度:O(1)
最容易想到的是暴力法,两层for循环,固定其中一个数,找另外一个数
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> 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);
return res;
}
}
}
return res;
}
};
哈希表(Two-pass Hash Table)
时间复杂度:O(n)
空间复杂度:O(n)
在暴力法中,固定其中一个数后,我们又需要遍历数组找到另一个数,那么有没有一种方法,固定一个数后,我们就能知道另一个数是否存在呢?这里很容易想到哈希表结构。首先我们把数组中的数都放到一个哈希结构中,固定一个数后,然后看哈希结构中是否存在另外一个数。这里需要注意,如果sum=4,当固定的数是2时,需要判断哈希结构存储的2是否是当前固定的数。
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> res;
//注意在STL中,unordered_map的底层结构是hashTable,map的底层是红黑树
unordered_map<int,int> hash;
//在hash结构中存储数与下标的关系
for(int i=0;i<nums.size();i++){
hash[nums[i]] = i;
}
for(int i=0;i<nums.size()-1;i++){
if(hash.find(target-nums[i])!=hash.end() && hash[target-nums[i]]!=i){
res.push_back(i);
res.push_back(hash[target-nums[i]]);
return res;
}
}
return res;
}
};
哈希表(One-pass Hash Table)
时间复杂度:O(n)
空间复杂度:O(n)
能不能再简洁一点?能不能遍历一次数组就能找到呢?我们可以在遍历过程中,将数组和下标的关系存储在哈希表中,与此同时,检测target-nums[i]是否在之前存储的哈希表中。
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> res;
unordered_map<int,int> hash;
for(int i=0;i<nums.size();i++){
if(hash.find(target-nums[i]) != hash.end()){
res.push_back(i);
res.push_back(hash[target-nums[i]]);
return res;
}
hash[nums[i]]=i;
}
return res;
}
};
目前只有C++版本的,希望有Java、Python…版的来投稿,欢迎大家来向专题(LeetCode题解)投稿,现在LeetCode有中文版的了,大家多刷刷题,找个好工作。