概述
我觉得这个模块就是为了让你知道哈希的用法
哈希:我觉得就是唯一的那种特性
哈希表的话就是类似一个函数,一个映射,所以我觉得它可以快速给我们对应的值

第一题
两数之和

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 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]
方法一:可以直接暴力破解,时间复杂度就是O(n²)
但是这个不太符合哈希
方法二:
使用HashMap
java
class Solution {
public int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> map = new HashMap<>();
for(int i = 0; i < nums.length; i++) {
if(map.containsKey(target - nums[i])) {
return new int[]{map.get(target - nums[i]), i};
}
map.put(nums[i], i);
}
return null;
}
}
首先你创建一个哈希表,key存储数组的值,value存对应的下标索引
在你遍历数组进行哈希表的put的时候判单是否已经存在值为target - nums[i]的元素,如果存在的话,直接返回这两个下标,这样就得到了这道题的答案。
注意点:
put一定是要放在判断之前,否则就会碰到两个一样的元素,因为不允许相同元素。
第二题

给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。
示例 1:
输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]
输出:[["bat"],["nat","tan"],["ate","eat","tea"]]
解释:
- 在 strs 中没有字符串可以通过重新排列来形成
"bat"。 - 字符串
"nat"和"tan"是字母异位词,因为它们可以重新排列以形成彼此。 - 字符串
"ate","eat"和"tea"是字母异位词,因为它们可以重新排列以形成彼此。
示例 2:
输入: strs = [""]
输出:[[""]]
示例 3:
输入: strs = ["a"]
输出:[["a"]]
这个就是字母异或表示的,这个哈希思想更加的强,
初始化:新建哈希表 key是原数组元素字符串的排序状态sorted,
然后值就是对应排序前的字符串的列表
java
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
List<List<String>> ans = new ArrayList<>();
Map<String, List<String>> m = new HashMap<>();
for(String s : strs) {
String key = sortString(s);
if(!m.containsKey(key)) {
m.put(key, new ArrayList<>());
}
m.get(key).add(s);
}
for(String s : m.keySet()) {
ans.add(m.get(s));
}
return ans;
}
private String sortString(String s) {
char[] chars = s.toCharArray();
Arrays.sort(chars);
return new String(chars);
}
}
辅助函数,这里面是排序字符串,然后返回一个新的字符串
首先遍历字符串数组,然后把新建一个key存储它排好序的值,value就放入它原来的值
然后判单这个put的是否已经存在,如果存在就放进它的list集合,不存在就put进哈希表
最后把每个小列表取出,再放进一个大列表返回
这里面更加快捷的方法是使用:
map.computeIfAbsent()方法,直接可以省去很多行代码。
第三题

java
class Solution {
public int longestConsecutive(int[] arr) {
int[] nums = Arrays.stream(arr).distinct().sorted().toArray();//这里是把原数组变成去重排数组
//如果长度小于等于1,直接返回长度
if(nums.length <= 1) {
return nums.length;
}
//这里就是判断最大的连续长度,如果后一个减去前一个等于1的话,说明这两个数字是连续的
int ans = 0;
int cnt = 1;
for(int i = 1; i < nums.length; i++) {
if((nums[i] - nums[i-1] == 1)) {
cnt++;
} else {
cnt = 1;
}
ans = Math.max(ans, cnt);
}
return ans;
}
}
这里面使用了stream流快速去重和排序,可以试试
其他的看注释,我觉得这个方法虽然效率不高,但是我的独特思路,大家可以参考一下