1. 两数之和 easy
思路
很明显暴力的解法是两层for循环查找,时间复杂度是O(n^2)。
什么时候使用哈希法?当需要查询一个元素是否出现过,或者一个元素是否在集合里的时候,就要第一时间想到哈希法。
这道题 我们需要 给出一个元素,判断这个元素是否出现过,如果出现过,返回这个元素的下标。
那么判断元素是否出现,这个元素就要作为key,所以数组中的元素作为key,有key对应的就是value,value用来存下标。
所以 map中的存储结构为 {key:数据元素,value:数组元素对应的下标}。
在遍历数组的时候,只需要向map去查询是否有和目前遍历元素匹配的数值,如果有,就找到的匹配对,如果没有,就把目前遍历的元素放进map中,因为map存放的就是我们访问过的元素。
在 Java 中,
Map
接口的containsKey()
和containsValue()
方法用于检查映射中是否包含特定的键或值。以下是这两个方法的详细介绍:1.
containsKey(Object key)
- 功能:检查映射中是否包含指定的键。
- 参数:一个对象
key
,可以是null
。- 返回值:如果映射中包含该键,则返回
true
;否则返回false。
2.
containsValue(Object value)
- 功能:检查映射中是否包含指定的值。
- 参数:一个对象
value
,可以是null
。- 返回值:如果映射中至少有一个键映射到该值,则返回
true
;否则返回false
。导包:
import java.util.HashMap;
import java.util.Map;
49.字母异位词分组 mid
思路
我们将每个字符串按照字母顺序排序,这样的话就可以把 eat,tea,ate 都映射到 aet。
复杂度分析
时间复杂度:排序的话算作 O(Klog(K)),最外层的 for 循环,所以就是 O(nKlog(K))。
空间复杂度:O(NK),用来存储结果。
额外题目
128.最长连续序列 mid
设计并实现时间复杂度为 O(n)
的算法解决此问题
每个数都判断一次这个数是不是连续序列的开头那个数。
- 怎么判断呢,就是用哈希表查找这个数前面一个数是否存在,即num-1在序列中是否存在。存在那这个数肯定不是开头,直接跳过。
- 因此只需要对每个开头的数进行循环,直到这个序列不再连续,因此复杂度是O(n)。 以题解中的序列举例:
[100,4,200,1,3,4,2]
去重后的哈希序列为:
[100,4,200,1,3,2]
按照上面逻辑进行判断:
- 元素100是开头,因为没有99,且以100开头的序列长度为1
- 元素4不是开头,因为有3存在,过,
- 元素200是开头,因为没有199,且以200开头的序列长度为1
- 元素1是开头,因为没有0,且以1开头的序列长度为4,因为依次累加,2,3,4都存在。
- 元素3不是开头,因为2存在,过,
- 元素2不是开头,因为1存在,过。
复杂度分析
时间复杂度:O(n),其中 n 为数组的长度。具体分析已在上面正文中给出。
空间复杂度:O(n)。哈希表存储数组中所有的数需要 O(n) 的空间。
560. 和为K的子数组 mid
思路
前缀和 + HashMap ,思路与两数之和类似
只不过我们是将所有的前缀和该前缀和出现的次数存到了 map 里
当前前缀和已知,判断是否含有 presum - k的前缀和,那么我们就知道某一区间的和为 k 了
作者:程序厨
链接:https://leetcode.cn/problems/subarray-sum-equals-k/solutions/562174/de-liao-yi-wen-jiang-qian-zhui-he-an-pai-yhyf/
来源:力扣(LeetCode)
其他题目
383. 赎金信 数组模拟