题目及说明:
给定一个整数数组 nums
和一个整数目标值 target
,请你在该数组中找出 和为目标值 target
的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
限制:
2 <= nums.length <= 104
-109 <= nums[i] <= 109
-109 <= target <= 109
- 只会存在一个有效答案
思路:
本题只有一个条件:两个数的和为target。
那么,我们先了解一下,一个长度为n的数组(n>=2),2个数有多少种组合方式?
n=2时,a、b,只有{{a,b}}1种。
n=3时,a、b、c,有{{a,b},{a,c},{b,c}}3种。
n=4时,a、b、c、d,有6种。
我们容易发现:在数组nums1中,添加一个元素(新数组命名为nums2),nums2的组合数,就相当于在nums1的基础上,使nums2与nums1的所有元素都组合一遍。
比如:n=2,与n=3,差别在于n=3时,c与a、b都组合了一遍。
n=3,与n=4,差别在于d与a/b/c组合了一遍。
【当然,观察也可得到,nums中元素的增加,与组合方式个数的增加,实际满足等差数列的关系】
当n++时,Sn与Sn-1的差值,与Sn-1与Sn-2的差值,恒差1。
如:当n=2,Sn=1,设a1=1;
当n=3,Sn=3,差值为2;
当n=4,Sn=6,差值为3;
当n=5,Sn=10,差值为4;
……
即差值是以a1=2,d=1的等差数列。【以差值2开始计算差值】
Sn的序列为1,3,6,10,15,21……
差值为2,3,4,5,6,7,8……
也就是满足,Sn=Sn-1+差值n(n-1)。
比如S2=S1+n1;S3=S2+n2。
又因为Sn-1=Sn-2+n(n-2)。
并且存在关系:n1=2,n2=3……n(n-1)=n,代入数字,即
Sn - Sn-1 = n,
Sn-1 - Sn-2 = n-1,
Sn-2 - Sn-3 = n-2,
……
S3 - S2 = 3,
S2 - S1 = 2.
左右全加,有:
Sn - S1 = n + n-1 + n-2 + …… + 3 + 2
又因为S1 = 1,故Sn = n + n-1 + …… + 1;
所有Sn = 0.5 * n * (n-1);
解题方法1(for嵌套遍历):
对于这个数据量,最经典、朴素的方法是:for循环嵌套遍历
拿到两个数据,相加判断是否为target(或者相减,其速度差不多)
这道题的难点,只在于如何遍历所有数据。
解题方法2(Hash表):
上述方法时间复杂度较高。
现在给你一张可以定位的表table,再给你一个target,和一个值num1,请你从表table中找到另一个num2,使得num2+num1=target。
我们不用遍历该表table,因为可以直接定位(table提供了定位方法get)
1.如何操作?【num1一定在结果集中】
直接table.get(target-num1),即可获得对应值。
然而,我们不需要值,而是需要数组对应的下标。
2.所以,该如何拿到下标呢?
如果是链表,我们应该在数据域中定义下标、值两个数据,这样就能定位。
问题解决了。
不过,链表的访问速度也比较慢,因为其不能随机访问,其查找效率为O(n)。
如果是一个排序好的数组,支持随机访问,好像效率高了。
可是问题又来了,最开始提供的工具里,没有排序好的数组,只有一个普通数组。
如果先排序再查找,由于在nums里不确定num1(两个数都不确定),所以还是需要遍历。
3.就算假设已经确定num1,排序算法的效率也很低。因此,有什么不需要过多的操作,可以快速访问数据的数据结构吗?
HashMap,由于该题只需要定位两个数字(下标、值),所以key、value的组合,恰好可以对应。
朴素的思想是,将下标存进HashMap的key,值存入HashMap的value中。
4.然而,HashMap的value与key并不是一一对应的关系,可能一个value对应几个key(类似函数y与x的关系),因此,Java没给我们提供根据value找key的方法。
反过来,一个key对应一个Value,所以干脆将下标存入value,值存入key中【因为下标具有唯一性,存入value后也能避免哈希冲突】
5.问题转换成了:我们没有天生的Hash结构,即使创建一个HashMap,里面也没有值。
因此,我们需要向HashMap中存入数据。
6.但是,如果先将数据存入,又有些慢了【假设存储n次,后续遍历n/2次,相加,时复为O(N),相对下面的慢一点】
所以,我们需要一边存储,一边查找。
7.什么意思?HashMap中没有数据,查找什么?
想一想,我们需要的是2个数据的下标,由于题目规定答案只有一组。
8.那么,如果哈希表中有数据1的下标,在数组nums中遇到数据2时,是不是可以不用查找其它数据?
综上所述,答案如下:
以上内容即我想分享的关于力扣热题1的一些知识。
我是蚊子码农,如有补充,欢迎在评论区留言。个人也是初学者,知识体系可能没有那么完善,希望各位多多指正,谢谢大家。