超市里的货物架调整
选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 中,每个字符能够同时出现的最大次数,这里的“同时出现”是指两个字符串中都包含该字符,并且计算的是该字符在两个字符串中出现次数的较小值之和。这个问题可以抽象为对两个字符串的字符频率进行统计,并找出两者共有的字符,然后对这些共有字符的频率取较小值并累加。
代码详解
-
初始化变量:
count用于记录两个字符串中共有字符的频率之和。ch1和ch2分别是字符串s和c转换成的字符数组,便于遍历。map1和map2是两个HashMap,用于存储字符串s和c中每个字符的频率。
-
统计字符频率:
- 通过遍历
ch1和ch2数组,使用getOrDefault方法更新map1和map2中每个字符的频率。
- 通过遍历
-
计算共有字符的频率之和:
- 遍历所有小写字母(
'a'到'z')。 - 检查当前字符是否同时存在于
map1和map2的键集中。 - 如果存在,则将两个
HashMap中该字符的频率的较小值累加到count中。
- 遍历所有小写字母(
-
返回结果:
- 返回
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 个小写字母的频率。
学习建议
- 掌握哈希表的基本操作:包括插入、查找和删除键值对等。
- 理解哈希表的内部原理:这有助于我们更好地理解和使用哈希表,特别是在处理冲突和负载因子等方面。
- 多做练习:通过刷题和实践,我们可以更好地掌握哈希表的应用和技巧。