【手绘算法】力扣 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

相关文章
|
28天前
|
算法
测试工程师的技能升级:LeetCode算法挑战与职业成长
这篇文章通过作者亲身体验LeetCode算法题的过程,探讨了测试工程师学习算法的重要性,并强调了算法技能对于测试职业成长的必要性。
42 1
测试工程师的技能升级:LeetCode算法挑战与职业成长
|
1月前
|
存储 索引
LeetCode------两数之和(3)【数组】
这篇文章介绍了LeetCode上的"两数之和"问题,提供了两种解法:一种是暴力求解法,通过双层循环遍历数组元素对查找两数之和为目标值的索引,时间复杂度为O(n^2);另一种是使用HashMap优化,通过存储元素值和索引,时间复杂度降低到O(n)。
LeetCode------两数之和(3)【数组】
|
1月前
|
算法 Java
LeetCode经典算法题:矩阵中省份数量经典题目+三角形最大周长java多种解法详解
LeetCode经典算法题:矩阵中省份数量经典题目+三角形最大周长java多种解法详解
36 6
|
1月前
|
存储 算法 Java
LeetCode经典算法题:打家劫舍java详解
LeetCode经典算法题:打家劫舍java详解
46 2
|
1月前
|
人工智能 算法 Java
LeetCode经典算法题:井字游戏+优势洗牌+Dota2参议院java解法
LeetCode经典算法题:井字游戏+优势洗牌+Dota2参议院java解法
37 1
|
1月前
|
存储 算法 Java
LeetCode经典算法题:预测赢家+香槟塔java解法
LeetCode经典算法题:预测赢家+香槟塔java解法
35 1
|
1月前
|
算法
LeetCode第1题两数之和
该文章介绍了 LeetCode 第 1 题两数之和的解法,通过使用 HashMap 来记录数组元素及其下标,以 O(n)的时间复杂度解决问题。
|
1月前
|
JavaScript 前端开发 PHP
leetcode——两数之和【一】
leetcode——两数之和【一】
21 0
|
1月前
|
存储 算法 Java
LeetCode经典算法题:二叉树遍历(递归遍历+迭代遍历+层序遍历)以及线索二叉树java详解
LeetCode经典算法题:二叉树遍历(递归遍历+迭代遍历+层序遍历)以及线索二叉树java详解
60 0
|
1月前
|
算法 Java
LeetCode初级算法题:子数组最大平均数+二叉树的最小深度+最长连续递增序列+柠檬水找零
LeetCode初级算法题:子数组最大平均数+二叉树的最小深度+最长连续递增序列+柠檬水找零
32 0