字母出现次数统计 | 豆包MarsCode AI 刷题

102 阅读4分钟

今天来整理一下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。

  1. 初始化map,此时map=[]

  2. 循环:

    • 当前字符为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]。
  3. 出循环

  4. 得出符合条件的字母数为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存储数据结构真的高效又便捷。

还会继续更新别的题目,下期再见咯!