Two Sum

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; }



原文地址:https://www.cnblogs.com/xiaolovewei/p/8057477.html