LeetCode No1 两数之和

题目

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target  的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。

示例 1:

输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。

示例 2:

输入:nums = [3,2,4], target = 6
输出:[1,2]

示例 3:

输入:nums = [3,3], target = 6
输出:[0,1]

提示:

2 <= nums.length <= 104
-10^9 <= nums[i] <= 10^9
-10^9 <= target <= 10^9
只会存在一个有效答案
进阶:你可以想出一个时间复杂度小于 O(n2) 的算法吗?

思路

暴力求解

首先,看到提示,发现数据量并不大,所以此题第一反应就是直接两个for循环暴力解决,只要找到两个数之和等于target即可。

桶方法(字典)

当数组的长度稍微大一点的时候,方法一可能就不能满足时间复杂度的要求了,而如果想要时间短,我们可以使用空间换时间的方法,使用桶的思想,但是看题目的数据范围,也不能直接用到数组桶,这个时候自然而然就想到了Map,以数组为桶,遍历数组,如果在Map中能找到target-nums[i]的值,那么这个就是解答,否则就把当前下标i,作为target-nums[i]的值存入Map中,这样时间复杂度就为O(n)了。

双指针

其实在想到桶排之前,我还想到有另一种方法,只是这种方法有点麻烦,时间复杂度为O(n*logn),方法就是先将数组复制一份,然后将其中一份排序,使用双指针的方法遍历排好序的数组,找到相加等于target的两个值之后,再去原数组中找对应下标。

AC代码

暴力求解

点击查看代码
class Solution {
	public int[] twoSum(int[] nums, int target) {
		int len = nums.length;
		for(int i=0; i<len-1; i++) {
			for(int j=i+1; j<len; j++) {
				if( nums[i] + nums[j] == target ) {
					return new int[]{i, j};
				}
			}
		}
		return new int[]{};
	}
}

桶方法(字典)

点击查看代码
class Solution {
    public int[] twoSum(int[] nums, int target) {
         HashMap<Integer, Integer> map = new HashMap<>();
         int len = nums.length;
         for(int i=0; i<len; i++) {
             Integer j = map.get(target-nums[i]);
             if( j!=null ) {
                 return new int[]{i, j};
             }
             map.put(nums[i], i);
         }
         return new int[]{};
    }
}

双指针

点击查看代码
class Solution {
    public int[] twoSum(int[] nums, int target) {
        int len = nums.length;
        int[] copyNums = new int[len];
        for(int i=0; i<len; i++) {
            copyNums[i] = nums[i];
        }
         Arrays.sort(copyNums);
         int low = 0;
         int high = copyNums.length - 1;
         Integer a = null;
         Integer b = -1;
         while( low < high ) {
             if( copyNums[low] + copyNums[high] == target ) {
                 a = copyNums[low];
                 b = copyNums[high];
                 break;
             } else if( copyNums[low] + copyNums[high] > target ) {
                 high --;
             } else {
                 low ++;
             }
         }

         if( a!=null && b!=null ) {
             low = -1;
             high = -1;
             for(int i=0; i<len; i++) {
                 if( nums[i]==a && low==-1) {
                     low = i;
                 }
                 if( nums[i]==b ) {
                     high = i;
                 }
             }
             return new int[]{low, high};
         }
         return new int[]{};
    }
}
posted @ 2022-04-05 17:35  Asimple  阅读(19)  评论(0编辑  收藏  举报