1. 两数之和 Two Sum

Given an array of integers nums and an integer target, return indices of the two numbers such that they add up to target.

You may assume that each input would have exactly one solution, and you may not use the same element twice.

You can return the answer in any order.

 

Example 1:

Input: nums = [2,7,11,15], target = 9
Output: [0,1]
Output: Because nums[0] + nums[1] == 9, we return [0, 1].

 

方法一:

     暴力法。

    以 [2,7,11,15]为例,先固定第一个元素2,然后查找之后的元素 7,11,15. 如果存在和9,则输出,如果不存在,则固定第二个元素7,查找之后的元素11,15.

   这样就是两层循环,第一层i从0到长度-2,第二层j从i+1到长度-1。

   

    int [] twoSum(int [] nums, int target){
        for (int i = 0 ; i < nums.length-1; i++){
            for( int j = i + 1; j < nums.length; j++){
                if(nums[i] + nums[j] == target){
                    return new int []{ i, j};
                }
            }
        }
        return new int []{ -1, -1};
    }

 

时间复杂度为O(n^2)

 

方法二:

对于A+B=C,如果已知A和C,就可以求出B来。

先将数组里的所有的数和位置放到hash map字典里。

这样对于第一层的元素i查找配对的元素时,不是进入第二层遍历查找,而是到hash map字典里查找。

  int [] two_sum_test(int [] nums, int target){

      Map<Integer,Integer> map = new HashMap<>();
      for (int i = 0; i < nums.length; i++){
          map.put(nums[i], i);
      }
      for(int i =0 ;i < nums.length;i++){
          if(map.containsKey(target-nums[i])){
              return new int []{i, map.get(target-nums[i])};
          }
      }
      return new int[]{-1, -1};
  }

时间复杂度为O(n)

 

方法三:

对于A+B=C,如果已知A和C,就可以求出B来。

我们可以在第一层遍历数据的时,可以把历史数据存到一个hash map里。

这样,对于第一层的元素i查找配对的元素时,不是进入第二层遍历查找,而是到历史hash map里查找有没有配对数据。

 

  int [] twoSum_sample(int [] nums,int target){
      Map<Integer,Integer> map=new HashMap<>();
      for (int i = 0; i < nums.length; i++){
          if(map.containsKey(nums[i])){
              return new int[]{map.get(nums[i]), i};
          }else{
              map.put(target - nums[i], i);
          }

      }
      return new int[]{-1, -1};
  }

 

时间复杂度为O(n)

 

方法四:

    将原数组赋值给新数组并对新数组排序,然后用双指针法查找位置。

    查找方法如下:令i =0, j = nums.length. 如果nums[i]+nums[j]>target, j--;如果nums[i]+nums[j]<target, i++;否则,找到i,j

    然后查找i,j在原数组中的位置。

 

    int [] two_sum_sort(int [] nums, int target){
        int [] sort_nums = new int[nums.length];
        for (int i = 0; i < nums.length; i++){
            sort_nums[i] = nums[i];
        }
        Arrays.sort(sort_nums,0,nums.length);
        int i = 0, j = sort_nums.length - 1;
        while(i < j){
            if(sort_nums[i] + sort_nums[j] > target) {
                j--;
            }else if (sort_nums[i] + sort_nums[j] < target){
                i++;
            }else{
                break;
            }
        }
        if(i >= j) {
            return new int[]{-1, -1};
        }
        int real_i = 0, real_j = 0;
        for (int real_pos = 0; real_pos < nums.length; real_pos++){
            if(nums[real_pos] == sort_nums[i]){
                real_i = real_pos;
            }
            if(nums[real_pos] == sort_nums[j]){
                real_j = real_pos;
            }
        }
        return new int[]{real_i, real_j};
    }

数组排序O(nlogn),双指针法遍历一遍O(n),总的时间复杂度O(nlogn)

 

参考链接

 

https://leetcode.com/problems/two-sum/solution/

https://leetcode-cn.com/problems/two-sum/

 

posted @ 2020-11-07 15:53  diameter  阅读(130)  评论(0)    收藏  举报