本专栏开启,目的在于帮助大家更好的掌握学习Java
,特别是一些Java学习者
难以在网上找到系统地算法学习资料帮助自身入门算法,同时对于专栏内的内容有任何疑问都可在文章末尾添加我的微信给你进行一对一的讲解。
但最最主要的还是需要独立思考,对于本专栏的所有内容,能够进行完全掌握,自己完完全全将代码写过一遍,对于算法入门肯定是没有问题的。
算法的学习肯定不能缺少总结,这里我推荐大家可以到高校算法社区将学过的知识进行打卡,以此来进行巩固以及复习。
学好算法的唯一途径那一定是题海战略,大量练习的堆积才能练就一身本领。专栏的任何题目我将会从【题目描述】【解题思路】【模板代码】【代码解析】等四板块进行讲解。
哈希函数我们在第20
天查找元素时粗略提过,今天我们来提到它的另外一种使用场景。统计一个数组内每个数出现次数,很明显我们需要一个东西去存储信息,而哈希函数恰好就能帮助我们解决这个问题,而这一般也称之为计数法。以值为key
,以出现的次数为value
。像这种计数的场景,也是非常常见且重要的知识点。
给定一个整数 n ( 1 ≤ n ≤ 1 e 5 ) n(1 \le n \le1e5) n(1≤n≤1e5) ,然后给定 n n n个整数 a i ( 1 ≤ 1 e 5 ) a_i(1 \le 1e5) ai(1≤1e5),统计每个数出现的次数并打印出来。
像序章所言,我们以数值为key
,以出现的次数为value
,利用哈希函数进行存储,由于每个数的值的范围在 [ 1 , 1 e 5 ] [1,1e5] [1,1e5],我们同样也可以使用数组模拟哈希表,下标替代数值,下标存储的值替代出现次数。
import java.util.*;
public class Main{
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
Map<Integer,Integer> map=new HashMap<>();
for (int i = 0; i < n; i++) {
int v=sc.nextInt();
map.put(v,map.getOrDefault(v,0)+1);
}
for (int i:map.keySet()){
System.out.println(i+"出现的次数为"+map.get(i));
}
}
}
import java.util.*;
public class Main{
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
int[] cnt=new int[100010];
for (int i = 0; i < n; i++) {
int v=sc.nextInt();
cnt[v]++;
}
for (int i = 0; i <=100000; i++) {
if (cnt[i]!=0){
System.out.println(i+"出现的次数为"+cnt[i]);
}
}
}
}
map.keySet
函数是拿到key
的映射集,帮助我们去遍历得到所有的value
,这种循环样式在Java
中称为增强for
循环。key
的值是多少,都可以直接进行存储,但由于涉及哈希碰撞以及函数调用等原因,效率肯定是不如数组哈希的。MLE
,这时得需要进行配合哈希来进行离散化,这就有点本末倒置了。如果值域还存在负数,还需要进行偏移,因为数组下标没有负数。序号 | 题目链接 | 难度评级 |
---|---|---|
1 | 设计哈希集合 | 1 |
2 | 设计哈希映射 | 1 |