基础知识 哈希表(Hash Table)
哈希表是根据关键码的值直接访问数据的数据结构,看了一个视频,感觉讲的很形象、很清楚👉哈希表是什么
hashCode把相应的字段转化为数值,hashCode通过特定编码方式,可以将其他数据格式转化为不同的数值。同时为了保证映射出来的索引数值都落在了哈希表上,我们会再次对数值做一个取模操作,保证所有字段都映射到哈希表上。
哈希碰撞
hash碰撞指的是,两个不同的值(比如张三、李四的学号)经过hash计算后,得到的hash值相同,后来的李四要放到原来的张三的位置,但是数组的位置已经被张三占了,导致冲突。参考👉哈希碰撞
拉链法
拉链法采用的是链表的方式,这个时候位置1就不单单存放的是Entry了,此时的Entry还要额外保存一个next指针,指向数组外的另一个位置,将李四安排在这里,张三那个Entry中的next指针就指向李四的这个位置,也就是保存的这个位置的内存地址。如果还有冲突,就把又冲突的那个Entry放到一个新位置上,然后李四的Entry指向它,这样就形成一个链表。参考👉哈希碰撞
线性探测法
如果使用线性探测法,那么一定要保证tableSize大于dataSize(数据规模),我们需要依靠哈希表的空位去解决碰撞问题。
例如:当前数组位置1被占用了,就放到下一个位置2上去,如果2也被占用了,就继续往下找,直到找到空位置。
常见的三种哈希结构
- 数组
- set集合
- map映射
当我们需要快速判断一个元素是否出现集合的时候,就要考虑使用哈希法
454.四数相加II
题目:
给你四个整数数组 nums1、nums2、nums3 和 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i, j, k, l) 能满足:
0 <= i, j, k, l < n
nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0
提示:
直接暴力解法时间复杂度为n²*n²可以在nums1中和nums2值中先相加找相同的值计数(假如找的值是a+b),再在nums3和nums4中查找c和d使其满足c+d=0-(a+b),这时时间复杂度为n²。
题解:
Java的哈希操作👉Java—HashMap
HashMap是一个散列表,它存储的内容是键值映射
HashMap的key与value的类型可以相同也可以不同
基本操作
- 定义哈希表
HashMap<Interger, String> hashmap = new HashMap<Integer, String>()
- 添加键值对(put)
hashmap.put(1, "string1"); // 执行完后hash表内为{1=string1}
hashmap.put(2, "string2"); // 执行完后hash表内为{1=string1, 2=string2}
hashmap.put(2, "string2"); // 执行完后hash表内为{1=string1, 2=string2, 3=string3}
- 根据key值访问value(get)
hashmap.get(1); // 返回string1
hashmap.get(2); // 返回string2
hashmap.get(3); // 返回string3
- 根据key值删除元素(remove)
hashmap.remove(1); // 执行完后hash表内为{2=string2, 3=string3}
hashmap.remove(2); // 执行完后hash表内为{3=string3}
hashmap.remove(3); // 执行完后hash表内为{}
// 删除所有键值对
hashmap.clear();
- 替换hashMap中指定的key对应的value
hashmap.replace(key,value);
- 返回hashmap中键值对的数量
hashmap.size();
- getOrDefault(Object key, V defaultValue)
hashmap.getOrDefault(key, defaultValue)
- entrySet() 方法可以与 for-each 循环一起使用,用来遍历迭代 HashMap 中每一个映射项
// foreach循环
for(var entry : map.entrySet()){
// 获得key
int key = entry.getKey();
// 获得value
int value = entry.getValue();
}
- 检查hashMap中是否存在指定的key对应的映射关系
hashmap.containsKey(key)
- 检查hashmap中是否存在指定的value对应的映射关系
hashmap.containsValue(value);
- 判断hashmap是否为空
hashmap.isEmpty();
java Solution
class Solution {
public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
Map<Integer, Integer> map = new HashMap();
int temp;
int res = 0;
// 统计两个数组中的元素之和,同时统计出现的次数,放入map
for(int i : nums1){
for(int j : nums2){
temp = i + j;
// 检查map中是否存在指定的key对应的映射关系
if(map.containsKey(temp)){
//如果存在,则将temp对应的value加1
map.put(temp, map.get(temp) + 1);
}
else{
// 如果不存在,则新建一个temp的key,给这个value赋值1
map.put(temp, 1);
}
}
}
// 统计剩余的两个元素的和,在map中查找是否存在相加为0的情况,同时记录次数
for(int i : nums3){
for(int j : nums4){
temp = i + j;
// 即判断是否存在nums1 + nums2 + nums3 + nums4 = 0的情况
if(map.containsKey(0 - temp)){
//如果存在,找到这个值的value,累加给res
res += map.get(0 - temp);
}
}
}
return res;
}
}
python solution
python中的hashmap就是常用的字典dict
# 代码逻辑和Java版本相同,不再赘述注释
class Solution(object):
def fourSumCount(self, nums1, nums2, nums3, nums4):
hashmap = dict()
for n1 in nums1:
for n2 in nums2:
if n1 + n2 in hashmap:
hashmap[n1+n2] += 1
else:
hashmap[n1+n2] = 1
count = 0
for n3 in nums3:
for n4 in nums4:
key = -n3 - n4
if key in hashmap:
count += hashmap[key]
return count
总结
这是第一遍刷代码随想录,现在时间也比较有限,每天先只做一道最基础的熟悉熟悉语法吧