Leetcode:1.两数之和

题目

给定一个整数数组 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 <= 10^4
  • -10^9 <= nums[i] <= 10^9
  • -10^9 <= target <= 10^9
  • 只会存在一个有效答案

进阶:你可以想出一个时间复杂度小于 O(n^2) 的算法吗?


此乃 Leetcode 第一题,搜题解找到了代码随想录的讲解,按照其中的讲解跟着敲了一遍,顺带学习了一下哈希表的知识。(同时参考了这个关于哈希表的视频

先来看代码随想录上总结中的四个问题

为什么会想到用哈希表?

查询一个元素是否出现过,或是一个元素是否存在集合中时,比如你要的和为9,现在遍历到了5,就要思考之前是否遍历过4。

  • 在遍历的同时,记录一些信息,以省去一层循环,这是“以空间换时间”的想法。
  • 需要记录已经遍历过的数值和它所对应的下标,可以借助查找表实现。
  • 题目没有要求key(数组元素)有序,所以使用哈希表而不是平衡二叉搜索树。(这是两个常用的查找表的实现)

哈希表为什么用map?

  • 因为本题,我们不仅要知道元素有没有遍历过,还要知道这个元素对应的下标,需要使用 key value结构来存放,key来存元素,value来存下标,那么使用map正合适。

本题map是用来存什么的?

  • 用来存放我们便利访问过的元素,因为遍历数组的时候,需要记录我们之前遍历过哪些元素对应的下标,这样才能找到与当前元素相匹配的(也就是相加等于target)

map中的key和value用来存什么的

  • {key:数组元素,value:数组元素对应的下标}
  • 题目要求查找数组元素是否出现过,所以数组元素为key

思路

复杂度分析

两层for循环的暴力解法的时间复杂度为O(n^2)。通过哈希表可以将寻找target – nums[i] 的时间复杂度变为O(1),因为每次遍历后都会把遍历过的元素放进集合map中,那么我们最差的情况也就是遍历到数组中最后一个数才会在map中找到对应的数。时间复杂度跟元素数量(或者说数组长度)有关,即时间复杂度为O(n)

过程


Java 代码

class Solution {
    public int[] twoSum(int[] nums, int target) {
        // 首先,创建一个长度为2的结果数组res,并检查输入数组nums是否为空或长度为0。如果是,就直接返回res
        int[] res = new int[2];
        if (nums == null || nums.length == 0){
            return res;
        } 
        Map<Integer, Integer> map = new HashMap<>();// 创建一个哈希映射map,用于存储数组中的每个元素和它的索引。
        // 遍历输入数组nums。对于数组中的每个元素,计算target减去该元素的值,得到temp。
        for(int i = 0; i < nums.length; i++){
        int temp = target - nums[i];
        // 检查map中是否包含temp作为键。如果包含,说明找到了两个数的和等于target,这两个数就是当前元素和map中键为temp的元素。将这两个元素的索引分别存储在res[1]和res[0]中,然后跳出循环。
        if(map.containsKey(temp)){
            res[1] = i;
            res[0] = map.get(temp);
            break;
        }
        map.put(nums[i], i);// 如果map中不包含temp,就将当前元素和它的索引添加到map中。 
        }
        return res;// 遍历结束后,返回结果数组res。 
    }
}

留下评论