给定一个整数数列,找出其中和为特定值的那两个数。
你可以假设每个输入都只会有一种答案,同样的元素不能被重用。
示例:
给定 nums = [2, 7, 11, 15], target = 9 因为 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1]
三种思路
一,就是两个for循环就OK,时间复杂度为O(n2),空间复杂度O(1).
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* twoSum(int* nums, int numsSize, int target) {
int *res=(int *)malloc(2*sizeof(int));
for(int i=0;i<numsSize-1;i++)
{
for(int j=i+1;j<numsSize;j++)
{
if(nums[i]+nums[j]==target)
{
res[0]=i;
res[1]=j;
}
}
}
return res;
}
第二种,先排序,然后用两个指针,一个从左移动,一个从右移动,时间复杂度O(nlogn){原因:排序最好的为O(nlogn),移动O(n)所以为O(nlogn)}
左移动:a[i]+a[j]<target.
右移动:a[i]+a[j]>target.
第三种,(看网上的,自己也不是很懂)时间复杂度O(n)
希望通过O(n)的时间复杂度完成要求。
第一遍遍历:将(target-a)和i 作为键值对,存入Hash表,遍历时间复杂度为O(n),第二遍遍历:查询在Hash表中有和当前数相同的key,每次查询时间复杂度为O(1),遍历时间复杂度为O(n),
总的时间复杂度是O(2n)。
class Solution {
public int[] twoSum(int[] nums, int target) {
Map<Integer,Integer> map =new HashMap();
int []a=new int[2];
for(int i=0;i<nums.length;i++)
{
map.put(target-nums[i],i);
}
for(int i=0;i<nums.length;i++)
{
//可能存在一个数x,满足x*2=target,i!=map.get(nums[i])可以避免
if(map.containsKey(nums[i])==true && i!=map.get(nums[i]))
{
a[0]=i < map.get(nums[i])?i:map.get(nums[i]);
a[1]=i > map.get(nums[i])?i:map.get(nums[i]);
break;
}
}
return a;
}
}