怒刷力扣(两数之和)

125 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第1天,点击查看活动详情

两数之和

WangScaler: 一个用心创作的作者。

声明:才疏学浅,如有错误,恳请指正。

前因

之前在沸点说过要刷算法,从每天一题开始。但是工作很忙、自己偷懒等等原因吧,导致目前为止很难做到。正好看到掘金推送的更文活动,觉着还是更文,能逼迫这自己刷下去。怒刷leecode,从简单难度开始,从第一题开始,持之以恒。

题目

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

你可以按任意顺序返回答案。

分析

暴力破解

最简单,最直观的解法。直接两层循环,第一层循环是从头到尾遍历,第二层循环就是从第一层遍历的数字后边开始遍历。两层循环的值相加为目标值,直接返回两层循环的下标即可。

我的思考

第一种暴力破解,时间复杂度无疑是很高的,肯定是不行的。

首先考虑的就是减少一次循环,不遍历肯定是不行的,那么能不能遍历一次就能实现呢?

首先,我们遍历的时候会拿到一个值,那么【另一个值】就是【目标值-当前值】,那么我们找到这个【另一个值】就行了。

那么我们怎么找【另一个值】就是当前的问题了。

也许我们遍历的【另一个值】在遍历到的【当前值】的前边,也许在遍历到的【当前值】的后边。

如果在前边,其实我们当前值就是遍历【前边那个数】的时候的【另一个值】,如果在后边,后边无疑就是我们所说的【另一个值】。

那么我们如果遍历前边的时候,暂时把他存起来,不就在后边的时候,还能拿到他吗?

那么接下来就是怎么存储起来,而且查找的时候还不用遍历。

首先我们想到的是HashMap。他通过hashcode快速定位到我们查找的元素。

而且我们需要的是元素的下标值,只需要把下标存入到value即可。

答案

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

复杂度

  • 时间复杂度:O(N),如果我们查找的元素在最后一个位置,那么我们要遍历完整个表,所以N就是我们数组的长度。我们的另一个元素是通过HashMap查找,时间复杂度为O(1)。
  • 空间复杂度:O(N),我们这里创建了一个HashMap,如果我们查找的元素在最后一个位置,那么我们的HashMap中会存入数组长度-1个元素,所以空间复杂度也是O(N)。

总结

HashMap是个好东西,相信以后还会用到他。HashMap也是面试中常问的面试题之一,不会的小伙伴,赶紧恶补一下吧。

都来了,点个赞再走呗!

关注WangScaler,祝你升职、加薪、不提桶!