【LeetCode-00001】两数和[难度:简单]

233 阅读1分钟

原题

L00001两数和
  给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
  你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案
    输入:nums = [2,7,11,15], target = 9
    输出:[0,1]
    解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。

来源:力扣(LeetCode)
难度:简单
链接:leetcode-cn.com/problems/tw…

解法

  这个问题的最基本形式是这样:给你一个数组和一个整数 target,可以保证数组中存在两个数的和为 target,请你返回这两个数的索引。
比如输入 nums = [3,1,2,3,7], target = 6,算法应该返回数组 [0,3],因为 3 + 3 = 6。

这个问题如何解决呢?首先最简单粗暴的办法当然是穷举了:

  1. 穷举
int[] twoSum(int[] nums, int target) {

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

    // 不存在
    return new int[] {-1, -1};
}

这个解法非常直接,时间复杂度 O(N^2),空间复杂度 O(1)。 我们可以通过哈希表减少时间复杂度:

  1. 哈希表   把数组的值跟它的下标位置存入哈希表,在后面查找时会非常方便快速,遍历数组,在哈希表中找当前位置值的另一半是否在哈希表中,即在数组中,存在那么直接返回这两个下标,反之,存入哈希表。
public class L00001TwoSum {
    public int[] twoSum(int[] nums, int target){
        //借用hashmap来存储对应的值跟下标
        HashMap<Integer, Integer> map = new HashMap<>();
        //获取数组长度    为了减少时间复杂度,但会增加空间复杂度
        int length = nums.length;
        for (int i=0;i<length;i++){//遍历数组
            //以当前数组的值为基准,获取目标值的另一半
            int tmp = target-nums[i];
            //查找另一半是否在map数组中,若存在,则当前数组元素符合条件
            if (map.containsKey(tmp)){
                return new int[]{map.get(tmp),i};
            }else {
                map.put(nums[i],i);//不存在就存入hash中
            }
        }
        //没有符合条件的,就返回空数组
        return new int[0];
    }
}