青训营X豆包MarsCode 超市里的货物架调整 | 豆包MarsCode AI刷题

99 阅读5分钟

超市里的货物架调整

选AI刷题中的“超市里的货物架调整”题目进行分析,以及个人解题思路的分析和知识点总结。

问题描述

在一个超市里,有一个包含 nn 个格子的货物架,每个格子中放有一种商品,商品用小写字母 a 到 z 表示。当顾客进入超市时,他们会依次从第一个格子查找到第 nn 个格子,寻找自己想要购买的商品。如果在某个格子中找到该商品,顾客就会购买它并离开;如果中途遇到一个空格子,或查找完所有格子还没有找到想要的商品,顾客也会离开。

作为超市管理员,你可以在顾客到来之前重新调整商品的顺序,以便尽可能多地出售商品。当第一个顾客进入后,商品位置不能再调整。你需要计算在最优调整下,最多可以卖出多少件商品。输入变量说明:

  • n:货物架的格子数
  • m:顾客想要购买的商品种类数
  • s:货物架上商品的初始顺序
  • c:顾客想要购买的商品种类

代码

import java.util.HashMap;
import java.util.Map;
    public static int solution(int n, int m, String s, String c) {
        int count=0;
        //用两个hashmap去储存它,返回同一个值中较小的值
        char[] ch1 = s.toCharArray();
        char[] ch2 = c.toCharArray();
        HashMap<Character,Integer> map1=new HashMap<>();
        HashMap<Character,Integer> map2=new HashMap<>();
      for (char ch : ch1) {
        map1.put(ch, map1.getOrDefault(ch, 0)+1);
      }
    for (char ch : ch2) {
        map2.put(ch, map2.getOrDefault(ch, 0)+1);
    }
    for(char i='a';i<='z';i++){
        if(map1.keySet().contains(i)&&map2.keySet().contains(i)){
            count+=Math.min(map1.get(i), map2.get(i));
        }
    }
        return count;
    }

    public static void main(String[] args) {
        System.out.println(solution(3, 4, "abc", "abcd") == 3);
        System.out.println(solution(4, 2, "abbc", "bb") == 2);
        System.out.println(solution(5, 4, "bcdea", "abcd") == 4);
    }
}

代码解析

思路

这段代码的主要功能是计算两个字符串 s 和 c 中,每个字符能够同时出现的最大次数,这里的“同时出现”是指两个字符串中都包含该字符,并且计算的是该字符在两个字符串中出现次数的较小值之和。这个问题可以抽象为对两个字符串的字符频率进行统计,并找出两者共有的字符,然后对这些共有字符的频率取较小值并累加。

代码详解

  1. 初始化变量

    • count 用于记录两个字符串中共有字符的频率之和。
    • ch1 和 ch2 分别是字符串 s 和 c 转换成的字符数组,便于遍历。
    • map1 和 map2 是两个 HashMap,用于存储字符串 s 和 c 中每个字符的频率。
  2. 统计字符频率

    • 通过遍历 ch1 和 ch2 数组,使用 getOrDefault 方法更新 map1 和 map2 中每个字符的频率。
  3. 计算共有字符的频率之和

    • 遍历所有小写字母('a' 到 'z')。
    • 检查当前字符是否同时存在于 map1 和 map2 的键集中。
    • 如果存在,则将两个 HashMap 中该字符的频率的较小值累加到 count 中。
  4. 返回结果

    • 返回 count,即两个字符串中共有字符的频率之和。

示例解释

  • 对于 solution(3, 4, "abc", "abcd"),共有字符是 'a''b''c',它们的频率分别是 [1, 1, 1] 和 [1, 1, 1, 1],取较小值后累加得到 3
  • 对于 solution(4, 2, "abbc", "bb"),共有字符是 'b',它们的频率分别是 [2, 1] 和 [2],取较小值后累加得到 2
  • 对于 solution(5, 4, "bcdea", "abcd"),共有字符是 'a''b''c''d',它们的频率分别是 [1, 1, 1, 1, 1] 和 [1, 1, 1, 1],取较小值后累加得到 4

知识总结

新知识点

  • HashMap 的使用HashMap 是一个基于哈希表的 Map 接口实现,它允许使用 null 值和 null 键。在这个问题中,HashMap 用于存储字符及其出现的频率。
  • getOrDefault 方法getOrDefault 方法用于获取指定键对应的值,如果指定的键不存在,则返回默认值。这个方法在统计字符频率时非常有用。
  • 字符遍历:通过遍历字符数组或字符串的每个字符,可以方便地处理字符串中的每个元素。

理解与分析

  • 时间复杂度:该算法的时间复杂度为 O(n + m + 26),其中 n 和 m 分别是两个字符串的长度。这是因为我们需要遍历两个字符串来统计字符频率(O(n + m)),然后遍历所有小写字母(O(26))来计算共有字符的频率之和。由于 26 是一个常数,所以总的时间复杂度可以简化为 O(n + m)。
  • 空间复杂度:空间复杂度为 O(1)(不考虑输入字符串本身所占用的空间),因为我们只使用了两个 HashMap 来存储字符频率,而 HashMap 的空间复杂度与存储的键值对数量有关,这里最多存储 26 个小写字母的频率。

学习建议

  • 掌握哈希表的基本操作:包括插入、查找和删除键值对等。
  • 理解哈希表的内部原理:这有助于我们更好地理解和使用哈希表,特别是在处理冲突和负载因子等方面。
  • 多做练习:通过刷题和实践,我们可以更好地掌握哈希表的应用和技巧。