0
点赞
收藏
分享

微信扫一扫

【第25天】给定一个长度为 n 的数组,统计每个数出现的次数 | 计数哈希

​​​​

学习指引

  • ​​序、专栏前言​​
  • ​​序、本章前言​​
  • ​​一、【例题1】​​
  • ​​1、题目描述​​
  • ​​2、解题思路​​
  • ​​3、模板代码​​
  • ​​哈希表​​
  • ​​数组哈希​​
  • ​​4、代码解析​​
  • ​​三、推荐专栏​​
  • ​​四、课后习题​​

序、专栏前言

   本专栏开启,目的在于帮助大家更好的掌握学习​​Java​​​,特别是一些​​Java学习者​​​难以在网上找到系统地算法学习资料帮助自身入门算法
   但最最主要的还是需要独立思考,对于本专栏的所有内容,能够进行完全掌握,自己完完全全将代码写过一遍,对于算法入门肯定是没有问题的。
   算法的学习肯定不能缺少总结,这里我推荐大家可以到​高校算法社区​将学过的知识进行打卡,以此来进行巩固以及复习。
  学好算法的唯一途径那一定是题海战略,大量练习的堆积才能练就一身本领。专栏的任何题目我将会从【题目描述】【解题思路】【模板代码】【代码解析】等四板块进行讲解。

序、本章前言

  哈希函数我们在第​​20​​​天查找元素时粗略提过,今天我们来提到它的另外一种使用场景。统计一个数组内每个数出现次数,很明显我们需要一个东西去存储信息,而哈希函数恰好就能帮助我们解决这个问题,而这一般也称之为计数法。以值为​​key​​​,以出现的次数为​​value​​。像这种计数的场景,也是非常常见且重要的知识点。

一、【例题1】

1、题目描述

,然后给定个整数,统计每个数出现的次数并打印出来。

2、解题思路

  像序章所言,我们以数值为​​key​​​,以出现的次数为​​value​​​,利用哈希函数进行存储,由于每个数的值的范围在,我们同样也可以使用数组模拟哈希表,下标替代数值,下标存储的值替代出现次数。

3、模板代码

哈希表

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]);
}
}
}
}

4、代码解析

  • ​​​map.keySet​​​函数是拿到​​key​​​的映射集,帮助我们去遍历得到所有的​​value​​​,这种循环样式在​​Java​​​中称为增强​​for​​循环。
  • 哈希函数和数组哈希有啥区别呢?其实本质原理是相同的,不过各有优缺点,我们分别讨论一下。
  • 哈希函数,优势在于不需要去考虑存储的​​​key​​的值是多少,都可以直接进行存储,但由于涉及哈希碰撞以及函数调用等原因,效率肯定是不如数组哈希的。
  • 数组哈希,优势在于数组的操作效率非常高,劣势在于如果存储的值范围非常大,那就需要开一个很大的数组,空间很浪费,做题容易​​​MLE​​,这时得需要进行配合哈希来进行离散化,这就有点本末倒置了。如果值域还存在负数,还需要进行偏移,因为数组下标没有负数。
  • 【第25天】给定一个长度为 n 的数组,统计每个数出现的次数 | 计数哈希_开发语言_09

课后习题

序号

题目链接

难度评级

1


​​ 设计哈希集合​​

1

2

​​ 设计哈希映射​​

1



举报

相关推荐

0 条评论