【手绘算法】力扣 1 两数之和(Two Sum)

简介: Hi,大家好,我是Tom。一个美术生转到Java开发的程序员。从今天开始,我将带大家每天刷一道题。我会用手绘的方式给大家讲解解题思路。在解题过程中,也会手写一些伪代码。当然,如果想要完整的源码的话,可以到我的个人主页简介中获取。今天给大家分享的是力扣启蒙题第1题,求两数之和。虽然很简单,但是它的通过率只有52%。

Hi,大家好,我是Tom。一个美术生转到Java开发的程序员。从今天开始,我将带大家每天刷一道题。我会用手绘的方式给大家讲解解题思路。在解题过程中,也会手写一些伪代码。当然,如果想要完整的源码的话,可以到我的个人主页简介中获取。

今天给大家分享的是力扣启蒙题第1题,求两数之和。虽然很简单,但是它的通过率只有52%。

e18d4555a19641e8a0743963f823f8ef.png

1、题干分析

首先,我们来分析一下这道题的题干。

17caf59bcc61487e8d30b41c6d6bc497.png

这道题目的内容是:

给定一个整数数组 nums 和一个整数目标值 target,需要在这个数组中找出 和为目标值 target 的 两个 整数,并返回它们的数组下标。并且每种输入只能对应一个答案,也就说每一个输入只能有一个输出,只要有两个数相加等于目标值就立即返回。另外,还说明了数组中同一个元素在答案里不能重复出现,也就是说不能拿同一个值累加两次以上。

官方也提供了几个示例,我们来看一下示例1:

d9fe8644e1744048a87b931e8b1ca81d.png

它输入的数组nums的值分别为2,7,11,15 ,输入的目标值target是9,输入结果应该为0 、1。因为,在输入的数组中2和7相加正好等于目标值9。所以输出为2和7这两个数组元素的下标,分别为0和1即可。这样就能把这道题解决了。

那对于这道题呢,我给出两种解题方法。第一种方法是暴力法求解,第二种方法是效率更高的哈希表求解。

fdf87ed8c9f34688a90761cdd74c9b7b.png

2、暴力法求解

首先,我们类看一下暴力求解法,首先,我们准备这样一个数组,我的target值依旧是9。那在这里来看暴力求解如何实现。我们可以用遍历的方式,

首先把数组中的第一个值11,拿出来和后面的2、7、15相加求解,看是不是等于9。

然后,再把2拿出来跟后面的7、15相加,看是不是有等于9的情况。

依次类推,把7拿出来跟后面的数相加,看是否等于9,

直到最后,把15拿出来。

7c291de4e4a84b6e93522789df5718bf.png

那代码逻辑,到底怎么做实现呢?

首先搞1个指针在11这里放着固定不动,然后,再搞一个指针从2这个位置开始往后移动。直到移到这个数组的末尾为止。

我们发现,第一轮遍历移到最后一个数15这个数字这里,还是不满足条件。

接下来,我们就要将这个固定不动的指针往后移到2的这个位置上来。那这个时候,我们第二个要移动指针应该从哪里开始呢?你看,如果我从11这里开始,其实我11跟2这两个数是已经相加过了,不满足条件的。

那这个可移动的指针可不可以从它本身,也就是2的这个位置开始呢?不可以,因为,题目上说了,我们不能重复用相同的元素相加。所以,我们第二个指针,应该移动到固定指针的后一个位置上去,也就是7的这个位置。

在这个时候,我们发现2和7相加正好等于9,所以,我们就直接返回结果了。当然,我们返回的不是2和7,而是返回2和7对应的下标位置,也就是1 和 2。到这里为止,后面的数就不用再遍历了,因为我们已经找到结果了。

这就是暴力法的伪代码,这个方法名称参数和返回值leetcode都会给你。

754b3bce2e714504a7627ca8383e1b01.png

3、哈希表求解

接下来,我们来分析一下哈希表求解。同样,我们还是这么一个数组11、2、7、15,target值还是9。哈希表求解的思路是这样的,首先我们拿目标值和数组中的每一个元素相减得到一个差值,看得到的这个值是不是在数组中存在,如果存在就直接返回这个元素所在的下标值。

c6f62a78d4a6428d80c02a58b7c3e6d9.png

比如,我们先拿9减去11,得到差值为-2,然后看数组中是不是存在-2,如果存在,就直接当前的下标。那么问题来了,我们要在数组中找到-2,是不是每次都遍历一遍这个数组呢?这样一来我们的时间复杂度就是O(N)会很高。

那有没有更高效的方式呢?这里我们可以用Hash表。在两数相减之前,我们把数组中的元素存到Hash表中。将元素的值作为Key,将元素对应的下标作为Value值。这个时候,11对应的下标为0,2对应的下标为1,7对应的下标为2,15对应的下标为3,这样Hash表就完成初始化了。

然后,再拿target和Hash表中的key相减得到差值,那我们在同一次遍历中就可以拿这个差值去Hash表中找对应的Key,如果存在,就将这个Key对应的值取出缓存起来。那么当前被减的这个数也可以直接缓存起来,这个时候,它的时间复杂度就是O(1),非常的快了。

接下来我们来看哈希表求解的伪代码。

c8865c5ecadf4262b228b8dc91afc081.png

以上就是我关于两数之和解题思路分享。这道题本质上就是去给定的范围搜索目标值,所以,主要考虑的核心要素是时间复杂度。当然,这道题还有其他很多种解法,比如使用双指针,四分法或者使用其他二分法;如果需要完整代码的小伙伴,可以在我的个人主页简介中获取。

0ca75c5301fc41f58744e6bdf04de8d1.png

我是被编程耽误的文艺Tom,如果我的分享对你有帮助,请动动手指一键三连分享给更多的人。关注我,面试不再难!


附:完整源码地址:

GitHub

https://github.com/gupaoedu-tom/exercise-leetcode/blob/main/src/main/java/com/gupaoedu/exercise/leetcode/TwoSum.java

GitEE

https://gitee.com/gupaoedu-tom/exercise-leetcode/blob/main/src/main/java/com/gupaoedu/exercise/leetcode/AddTwoNumbers.java

相关文章
|
2月前
|
存储 算法 JavaScript
怎么刷算法,leetcode上有哪些经典题目
怎么刷算法,leetcode上有哪些经典题目
18 0
|
2月前
|
算法
LeetCode刷题---167. 两数之和 II - 输入有序数组(双指针-对撞指针)
LeetCode刷题---167. 两数之和 II - 输入有序数组(双指针-对撞指针)
|
1月前
【Leetcode】两数之和,给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
【Leetcode】两数之和,给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
|
2天前
leetcode代码记录(两数之和
leetcode代码记录(两数之和
7 1
|
2天前
|
算法 C语言 C++
|
2天前
leetcode代码记录(有序数组两数之和
leetcode代码记录(有序数组两数之和
10 0
|
5天前
|
存储 算法
Leetcode 30天高效刷数据结构和算法 Day1 两数之和 —— 无序数组
给定一个无序整数数组和目标值,找出数组中和为目标值的两个数的下标。要求不重复且可按任意顺序返回。示例:输入nums = [2,7,11,15], target = 9,输出[0,1]。暴力解法时间复杂度O(n²),优化解法利用哈希表实现,时间复杂度O(n)。
16 0
|
13天前
|
算法
LeetCode-1:两数之和
LeetCode-1:两数之和
|
22天前
|
算法
代码随想录算法训练营第六十天 | LeetCode 84. 柱状图中最大的矩形
代码随想录算法训练营第六十天 | LeetCode 84. 柱状图中最大的矩形
20 3
|
22天前
|
存储 算法
代码随想录算法训练营第五十九天 | LeetCode 739. 每日温度、496. 下一个更大元素 I
代码随想录算法训练营第五十九天 | LeetCode 739. 每日温度、496. 下一个更大元素 I
22 1