今天来整理一下Map有关的方法以及算法实战。(准确来说是HashMap相关知识,我也只用过HashMap做过关于Map的算法题O.o)
从我早上在MarsCode AI刷题做的题目入手,字母出现次数统计。难度等级:中等。我自己觉得并不难,只要可以合理运用Map相关知识,基本上是可以在10min内把它写出来。
话不多说,开整!
Map相关知识
Map类是Java集合框架中的一部分,用于存储键值对(key-value pairs)。每个键(key)对应一个值(value),键是唯一的,但值可以重复。
我也刷了挺多到Map相关的算法题目,觉得其实很多题目只是换了一个外壳,实际上万变不离其宗,而且使用的方法也基本就那几个。通过我刷题过程中用到的Map知识,总结出以下几种Map常用方法:
map.put(k, v):map中插入元素的方法。记得,插入map时需要以键值对的形式。map.get(k):获取该key所对应的value值。map.containsKey(k):该方法返回的值是一个boolean值,用于判断该map中是否存在该key。map.remove(k):通过key移除map中的对应键值对。
以及这几种我常常见到但是没有用过的方法:
map.containsValue(v):该方法返回的值是一个boolean值,用于判断该map中是否存在该value。map.values():返回Collection,所有value的可重复集合。map.entrySet():返回Set<Map.Entry<String, Integer>>,所有key-value映射关系。map.getOrDefault(k, v):判断当前key在map中是否出现,如果不出现则插入k并将k对应的value设置为v。
大家如果感兴趣可以去看一下这篇文章,他讲的方法很清晰,而且配有案例。
字母出现次数统计
问题描述
小R得到了一个由小写字母组成的字符串
s,她想知道有多少个小写字母在字符串中至少出现了k次。请你帮她解决这个问题。样例:
- 输入:
s = "zzzzzzabc", k = 3- 输出:
1
问题分析
这道题涉及到键值对问题,对于字符串s中的每个字符,我们需要统计它出现的次数,然后再与k作比较,最后得出答案。使用map刚好将s中的字符作为key、出现次数作为value,我们只需要先创建好字符串与出现次数的map,再通过比较k,这道题就完成了。
代码实现
import java.util.HashMap;
import java.util.Map;
public class Main {
public static int solution(String s, int k) {
Map<Character, Integer> map = new HashMap<>();
for (int i = 0; i < s.length(); i++) {
if (map.containsKey(s.charAt(i))) {
map.put(s.charAt(i), map.get(s.charAt(i)) + 1);
} else {
map.put(s.charAt(i), 1);
}
}
int count = 0;
for(Map.Entry<Character, Integer> entry : map.entrySet()){
if(entry.getValue() >= k){
count++;
}
}
return count;
}
public static void main(String[] args) {
System.out.println(solution("aaabcd", 2) == 1);
System.out.println(solution("aacbcbdefghijklmnopqrstuvwxyz", 1) == 26);
System.out.println(solution("zzzzzzabc", 3) == 1);
}
}
代码分析
- 首先,初始化map。
- 遍历字符串,使用
map.containsKey判断map中是否存在该字符。如果存在,则将该字符对应的value加一;如果不存在,则将字符对应的value初始化为1. - 至此,用来存储
字符-出现次数键值对的map创建完成。
- 初始化计数器。
- 循环,通过
map.entrySet()将当前键值对关系赋值给entry,通过getValue()得到出现字符的次数,与k作比较,符合条件的计数器就加一。 - 因为本道题只需要求出符合条件的字母的种类数量,不关心具体的字母是什么,所以到这里整道题就结束了。
实例解析
以测试用例中的"aaabcd", 2为例子,s = "aaabcd",k = 2。
-
初始化map,此时map=[]
-
循环:
- 当前字符为
a,map中不存在该字符,故插入该字符对应value设为1。此时map=[a=1]。 - 当前字符为
a,map中存在该字符,故在原本的基础上value+1。此时map=[a=2]。 - 当前字符为
a,map中存在该字符,故在原本的基础上value+1。此时map=[a=3]。 - 当前字符为
b,map中不存在该字符,故插入该字符对应value设为1。此时map=[a=3, b=1]。 - 当前字符为
c,map中不存在该字符,故插入该字符对应value设为1。此时map=[a=3, b=1, c=1]。 - 当前字符为
d,map中不存在该字符,故插入该字符对应value设为1。此时map=[a=3, b=1, c=1, d=1]。
- 当前字符为
-
出循环
-
得出符合条件的字母数为1。
代码改进
原代码的第7行到第13行可以改进为:
for (int i = 0; i < s.length(); i++) {
map.put(s.charAt(i), map.getOrDefault(s.charAt(i), 0) + 1);
}
思想不变,这样处理代码更加简洁。
小结
用map作为key-value存储数据结构真的高效又便捷。
还会继续更新别的题目,下期再见咯!