算法学习之哈希表
前言
从这篇开始,我们又进入了一个新的领域的学习,也就是集合。
学习数组,在数组中查找数据,我们会感觉很方便,但是遇到需要在数组中某个元素的增删,往往又会很耗费资源
学习链表,在链表中对特定或者是需要的元素进行增删时,也是极佳的解决方案,但是涉及到查找结点值时却也束手无策
而本系列的学习,我们会对两者间“取其精华、弃其糟粕”,本系列会先对哈希表这一数据结构进行学习、后面再对其它常见的集合进行学习、剖析,话不多说,我们开始学习!
一、哈希表
1.什么是哈希表
哈希表,英文名称“Hash Table”,又称散列表,它是根据关键码的值直接进行访问的数据结构,因而其结构大致为这样:
key:意为关键字,它是唯一的,又常称之为键;
value:意为值,值并不为一,通常是需要寻找的元素
因此,哈希表往往是以key—value形式进行对应,所以它们又常常被叫成键值对
2.关于API文档中HashTable
3.代码随想录中的经典讲解
①通过哈希函数来快速查询学生是否在学校
将学生姓名通过hashcode()函数转换成数值,这样就将名字映射成索引数值了,为了避免数值过长超过哈希表的大小,我们往往会采用取余操作,这样就可以保证学生姓名一定在哈希表上了
②哈希冲突
我们知道,取余后两个数值将很有可能会得到相同的数值,那么它们的映射到同一索引,这就是哈希冲突,如何解决呢?方案有很多,比如线性探测法、二次探测再散列法等,感兴趣的可以自己去康康
4.常见的哈希结构
1.数组
2.Set (集合)
3.Map(映射)
二、小试牛刀,解决问题
1.有效的字母异位词
leetcode 242:有效的字母异位词
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词。
这就是哈希表典型的应用了
class Solution {
public boolean isAnagram(String s, String t) {
if(s.length()!=t.length())
return false;
Map<Character,Integer> map=new HashMap<Character,Integer>();
char[] cs=s.toCharArray();
char[] ct=t.toCharArray();
for(char ch:cs){
map.put(ch,map.getOrDefault(ch,0)+1);
}
for(char ch:ct){
map.put(ch,map.getOrDefault(ch,0)-1);
if(map.get(ch)<0)
return false;
}
return true;
}
}
2.394.两个数组的交集:
题目:
class Solution {
public int[] intersection(int[] nums1, int[] nums2) {
if(nums1==null||nums1.length==0||nums2==null||nums2.length==0)
return new int[0];
Set set=new HashSet<>();
Set<Integer> resSet=new HashSet<>();
for(int i=0;i<nums1.length;i++){
set.add(nums1[i]); //将数组1中的元素添加进set容器中
}
for(int i=0;i<nums2.length;i++){
if(set.contains(nums2[i]))
resSet.add(nums2[i]); //将数组1中存在的元素中和nums2比较,将重合的部分加入容器
}
//将resSet的元素转换成数组元素
int[] result=new int[resSet.size()];
int index=0;
for(int num:resSet){
result[index++]=num;
}
return result;
}
}