算法学习-查找数组中两个值的和为目标值
算法学习-查找数组中两个值的和为目标值
告别浮躁,回归初心
从简单入手
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。假设只存在一个有效答案
示例 1:
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
示例 2:
输入:nums = [3,2,4], target = 6
输出:[1,2]
示例 3:
输入:nums = [3,3], target = 6
输出:[0,1]
开发常用
public static int[] twoSum(int[] nums, int target) { int[] index = new int[2]; for (int i = 0; i < nums.length; i++) { for (int j = i; j < nums.length; j++) { if (nums[i] + nums[j] == target) { index[0] = i; index[1] = j; } } } return index; }
类似于游标的做法

这是常用的做法,在开发中也差不多这种用的最普遍,老师教学中也常用此作为教学
缺点,时间复杂度高,运行时间长
改进算法
利用hashmap的hashkey作为目标数去查找
public int[] twoSum(int[] nums, int target) { HashMap<Integer,Integer> map = new HashMap<>(); for(int i = 0; i < nums.length; i++){ if(map.containsKey(nums[i])){
//如果保存的hashmap中恰好存在 target-X的key则返回 return new int[]{map.get(nums[i]), i}; } map.put(target - nums[i], i); } return null; }
利用Hashmap,使用hash key作为查询,对大数据可以做到快速定位和查找。只需循环查找一次,查到下一个数据,用目标数减去当前数值后的key如果存在,则返回。
衍生知识
Hashmap快速存储特点原理
数组和链表各自特点
数组:
存储区间是连续,且占用内存严重,空间复杂也很大,时间复杂为O(1),是随机读取效率很高,原因数组是连续(随机访问性强,查找速度快)。
插入和删除数据效率低,因插入数据,这个位置后面的数据在内存中要往后移的,且大小固定不易动态扩展。
链表
区间离散,占用内存宽松,空间复杂度小,时间复杂度O(N),插入删除速度快,内存利用率高,没有大小固定,扩展灵活
不能随机查找,每次都是从第一个开始遍历(查询效率低)。
能否集两家所长,实现查询效率高和插入删除效率也高的数据结构,答案是肯定的
哈希表
map.put(k,v)实现原理
- 首先将k,v封装到Node对象当中(节点)。
- 底层会调用K的hashCode()方法得出hash值。
- 通过哈希表函数/哈希算法,将hash值转换成数组的下标,下标位置上如果没有任何元素,就把Node添加到这个位置上。如果说下标对应的位置上有链表。此时,就会拿着k和链表上每个节点的k进行equal。如果所有的equals方法返回都是false,那么这个新的节点将被添加到链表的末尾。如其中有一个equals返回了true,那么这个节点的value将会被覆盖。
map.get(k)实现原理
- 先调用k的hashCode()方法得出哈希值,并通过哈希算法转换成数组的下标。
- 通过上一步哈希算法转换成数组的下标之后,在通过数组下标快速定位到某个位置上。重点理解如果这个位置上什么都没有,则返回null。如果这个位置上有单向链表,那么它就会拿着参数K和单向链表上的每一个节点的K进行equals,如果所有equals方法都返回false,则get方法返回null。如果其中一个节点的K和参数K进行equals返回true,那么此时该节点的value就是我们要找的value了,get方法最终返回这个要找的value。
总结下就是如图

使用hash算法算出hash值,然后将hash值转换成数组的下标。若数组那里不存在值,则存入该值;若已经存在,则延长为链表跟在后面。插入和查询以此类推
理论上该算法时间复杂度最高为O(1),随着数据量增大,冲突过多一定会大于O(1)。
附: JDK8之后,当链表元素为6个和8个分别作为红黑树转链表,链表转红黑树的阈值。

参考资料

浙公网安备 33010602011771号