题目:
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.
Example:
Given nums = [2, 7, 11, 15], target = 9, Because nums[0] + nums[1] = 2 + 7 = 9, return [0, 1].
UPDATE (2016/2/13):
The return format had been changed to zero-based indices. Please read the above updated description carefully.
题意:
从给定的数组中找到两个数相加之后的和等于给定的数,返回数组中两个元素的下标。
思路一:双重循环
最简单的思路,两重循环,没啥技术含量,速度很慢,毕竟是$O(N^2)$ ```
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[i]+nums[j]==target){
result.push_back(i);
result.push_back(j);
}
}
}
return result;
}
};
思路二:排序
其实简单的想,用一个排序都能把复杂度降到$O(NlogN)$,通过排序,然后用两个指针从前后扫描逼近真值(注意这个思想,可以让O(N*N)的复杂度降为O(N),充分利用排序,因为一定会有一个值满足,然后通过值去原数组里找对应的下标(这里其实就可以考虑,如果当初就用一个数据结构存好键值对应关系就好了,其实就是hashmap,下面的做法就用到了) (下面代码是 dugu9sword写的java代码,还是比较好理解的)。
public class Solution {
public int[] twoSum(int[] nums, int target) {
int[] nums_sorted=new int[nums.length];
System.arraycopy(nums,0,nums_sorted,0,nums.length);
//Quicksort.
Arrays.sort(nums_sorted);
//Find the two numbers. O(n)
int start=0;
int end=nums_sorted.length;
while(start<end){
while(nums_sorted[start]+nums_sorted[--end]>target);
if(nums_sorted[end]+nums_sorted[start]==target)
break;
while(nums_sorted[++start]+nums_sorted[end]<target);
if(nums_sorted[end]+nums_sorted[start]==target)
break;
}
//find the indices of the two numbers
int[] ret=new int[2];
int index=0;
int a=nums_sorted[start];
int b=nums_sorted[end];
for(int i=0;i<nums.length;i++)
if(nums[i]==a || nums[i]==b)
ret[index++]=i;
return ret;
}
}
思路三:Hashmap
最后一种是比较聪明的做法,用hashmap,hashmap是内部存储方式为哈希表的map结构,哈希表可以达到查找O(1),哈希表的介绍可以看这里, C++实现Hashmap的方式,这里用unordered_map关联容器,可以实现键值对应,java使用hashmap就行了。
class Solution{
public:
vector<int> twoSum(vector<int>& nums, int target){
unordered_map mapping;
vector<int> result;
for(int i=0; i<nums.size(); i++){
mapping[nums[i]] = i;
}
for(int i=0; i<nums.size(); i++){
const int gap = target - nums[i];
if(mapping.find(gap)!=mapping.end() && mapping[gap]>i){
result.push_back(i);
result.push_back(mapping[gap]);
break;
}
}
return result;
}
};