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].
题目意思是给定一个数组和一个整数,从数组中找出两个数的和为目标整数。且返回的是两个整数的下标。数组中最多只有一对数据满足要求。
暴力解法:双重遍历,复杂度o(n^2).
O(n)思路:因为要与下标有关,将数据与下标换种方式联系起来,此时可以想到map。
但是,如果只是将map作为存储结构,先存储完,然后再进行查找,这跟暴力解法是一样的。
我们应该注意到,假设两个数是a,b满足a+b=target.如果a在map中,那么target-a(也就是b)肯定也在map中。
注意到这一点以后,我们可以在存数据nums[i]到map中去的同时就进行判断,如判断target-nums[i]是否在里面,如果不在,则存入nums[i],如果在,就找到了。
代码:
class Solution { public int[] twoSum(int[] nums, int target) { int[] result=new int[2]; HashMap<Integer,Integer> map=new HashMap<>(); for(int i=0;i<nums.length;i++){ if(map.containsKey(target-nums[i])){ //存数据之前,判断target-nums[i]是否已经存在,如果存在就找到了 result[1]=i; result[0]=map.get(target-nums[i]); return result; }else{ map.put(nums[i], i); //依次将数据存进去 } } return result; } }
还有一种不是特别好的方法,可以将数组排序,但是排序后下标会发生变化,所以用另外一个数组c来表示此数组,注意,c不能直接指向原数组,因为这算是引用,操作c数组也就是操作原数组。所以要对c数组重新赋值。排序后,从两端向中间找,因为此时下标不是原数组的下标,则只能记录找到的元素,然后根据元素,去原数组找到相应的下标
public static int[] twoSum(int[] nums, int target) { int[] co=new int[nums.length];
//赋值nums数组到co数组中。不能co=nums直接指向,这是引用 for(int l=0;l<nums.length;l++){ co[l]=nums[l]; } Arrays.sort(co); int[] a=new int[2]; int i,j;
//找出符合的元素在新数组的下标, for( i=0,j=co.length-1;i<j;){ if(co[i]+co[j]==target){ break; }else if(co[i]+co[j]>target) { j--; }else { i++; } } a[0]=-1; a[1]=-1;
//根据找到的元素,去原数组找相应的下标。 for(int k=0;k<nums.length;k++){ if(nums[k]==co[i]&&a[0]==-1) {a[0]=k;continue;} if(nums[k]==co[j]&&a[1]==-1) a[1]=k; } if(a[0]>a[1]){ int tem=a[0]; a[0]=a[1]; a[1]=tem; } return a; }