【手绘算法】力扣 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月前
|
算法
Leetcode 初级算法 --- 数组篇
Leetcode 初级算法 --- 数组篇
41 0
|
1月前
|
存储 算法 Java
leetcode算法题-有效的括号(简单)
【11月更文挑战第5天】本文介绍了 LeetCode 上“有效的括号”这道题的解法。题目要求判断一个只包含括号字符的字符串是否有效。有效字符串需满足左括号必须用相同类型的右括号闭合,并且左括号必须以正确的顺序闭合。解题思路是使用栈数据结构,遍历字符串时将左括号压入栈中,遇到右括号时检查栈顶元素是否匹配。最后根据栈是否为空来判断字符串中的括号是否有效。示例代码包括 Python 和 Java 版本。
|
2月前
|
算法
【链表】算法题(二) ----- 力扣/牛客
【链表】算法题(二) ----- 力扣/牛客
|
2月前
|
C++
Leetcode第一题(两数之和)
这篇文章介绍了解决LeetCode第一题“两数之和”的两种方法:暴力法和哈希表法,并提供了相应的C++代码实现。
39 0
Leetcode第一题(两数之和)
|
2月前
|
存储 C++ 容器
【LeetCode 13】1.两数之和
【LeetCode 13】1.两数之和
16 0
|
2月前
|
算法
【链表】算法题(一) ----- 力扣 / 牛客
【链表】算法题(一) ----- 力扣 / 牛客
|
2月前
|
算法
【顺序表】算法题 --- 力扣
【顺序表】算法题 --- 力扣
|
4月前
|
算法
测试工程师的技能升级:LeetCode算法挑战与职业成长
这篇文章通过作者亲身体验LeetCode算法题的过程,探讨了测试工程师学习算法的重要性,并强调了算法技能对于测试职业成长的必要性。
78 1
测试工程师的技能升级:LeetCode算法挑战与职业成长
|
4月前
|
存储 索引
LeetCode------两数之和(3)【数组】
这篇文章介绍了LeetCode上的"两数之和"问题,提供了两种解法:一种是暴力求解法,通过双层循环遍历数组元素对查找两数之和为目标值的索引,时间复杂度为O(n^2);另一种是使用HashMap优化,通过存储元素值和索引,时间复杂度降低到O(n)。
LeetCode------两数之和(3)【数组】