解析与图解
问题描述
在一个超市中,有一个包含 n 个格子的货物架,每个格子中放有一种商品,商品用小写字母 a 到 z 表示。顾客进入超市后,会依次从第一个格子查找到第 n 个格子,寻找他们想要购买的商品。如果在某个格子中找到该商品,顾客就会购买它并离开;如果中途遇到一个空格子,或者查找完所有格子还没有找到想要的商品,顾客也会离开。
作为超市管理员,你可以在顾客到来之前重新调整商品的顺序,以便尽可能多地出售商品。当第一个顾客进入后,商品位置不能再调整。目标是计算在最优调整下,最多可以卖出多少件商品。
输入变量说明
n:货物架的格子数。m:顾客想要购买的商品种类数。s:货物架上商品的初始顺序(长度为n的字符串)。c:顾客想要购买的商品种类(长度为m的字符串)。
示例分析
让我们通过示例来理解问题:
-
示例 1:
- 输入:
n = 3,m = 4,s = "abc",c = "abcd" - 输出:
3 - 解释: 顾客想要购买
a,b,c,d。货架上有a,b,c。最优调整下,可以卖出a,b,c,共 3 件商品。
- 输入:
-
示例 2:
- 输入:
n = 4,m = 2,s = "abbc",c = "bb" - 输出:
2 - 解释: 顾客想要购买
b。货架上有a,b,b,c。最优调整下,可以卖出 2 个b。
- 输入:
-
示例 3:
- 输入:
n = 5,m = 4,s = "bcdea",c = "abcd" - 输出:
4 - 解释: 顾客想要购买
a,b,c,d。货架上有b,c,d,e,a。最优调整下,可以卖出a,b,c,d,共 4 件商品。
- 输入:
算法思路
为了在最优调整下尽可能多地卖出商品,我们需要:
- 统计货架上每种商品的数量。
- 统计顾客想要购买的每种商品的数量。
- 计算每种商品在货架上的数量与顾客需求的数量之间的最小值,即每种商品最多可以卖出的数量。
- 将所有商品的最大可卖出数量相加,得到最终结果。
图解
假设输入为 n = 5, m = 4, s = "bcdea", c = "abcd":
- 货架上的商品:
b,c,d,e,a - 顾客想要的商品:
a,b,c,d
统计货架上每种商品的数量:
a: 1b: 1c: 1d: 1e: 1
统计顾客想要购买每种商品的数量:
a: 1b: 1c: 1d: 1
计算每种商品最多可以卖出的数量:
a: min(1, 1) = 1b: min(1, 1) = 1c: min(1, 1) = 1d: min(1, 1) = 1
总销售量:1 + 1 + 1 + 1 = 4
代码详解
import java.util.HashMap;
public class Main {
public static int solution(int n, int m, String s, String c) {
// 统计货架上每种商品的数量
HashMap<Character, Integer> shelfCount = new HashMap<>();
for (char item : s.toCharArray()) {
shelfCount.put(item, shelfCount.getOrDefault(item, 0) + 1);
}
// 统计顾客想要的商品种类
HashMap<Character, Integer> customerCount = new HashMap<>();
for (char item : c.toCharArray()) {
customerCount.put(item, customerCount.getOrDefault(item, 0) + 1);
}
// 计算最多能卖出的商品数量
int totalSales = 0;
for (char item : customerCount.keySet()) {
if (shelfCount.containsKey(item)) {
totalSales += Math.min(shelfCount.get(item), customerCount.get(item));
}
}
return totalSales;
}
public static void main(String[] args) {
// 测试样例
System.out.println(solution(3, 4, "abc", "abcd") == 3); // 输出: true
System.out.println(solution(4, 2, "abbc", "bb") == 2); // 输出: true
System.out.println(solution(5, 4, "bcdea", "abcd") == 4); // 输出: true
}
}
-
统计货架上的商品数量:
- 使用
HashMap记录每种商品在货架上的数量。 - 遍历字符串
s,将每种商品的数量存入shelfCount。
- 使用
-
统计顾客想要的商品种类:
- 同样使用
HashMap记录每种商品在顾客需求中的数量。 - 遍历字符串
c,将每种商品的需求数量存入customerCount。
- 同样使用
-
计算总销售量:
- 遍历
customerCount中的每种商品。 - 对于每种商品,检查货架上是否存在该商品。
- 如果存在,计算货架上数量与顾客需求数量的最小值,并加到
totalSales中。
- 遍历
-
返回结果:
- 返回
totalSales,即最多可以卖出的商品数量。
- 返回
知识点总结
-
HashMap 的使用:
HashMap是 Java 中常用的数据结构,用于存储键值对。getOrDefault方法可以简化代码,避免显式地检查键是否存在。
-
字符串遍历:
- 使用
toCharArray()方法将字符串转换为字符数组,方便遍历。
- 使用
-
字符与字符串处理:
- 字符用
char类型表示,字符串用String类型表示。 - 字符与字符串之间的转换可以通过
String类的构造方法实现。
- 字符用
-
时间复杂度:
- 本算法的时间复杂度为 O(n + m),其中
n是货架上的商品数量,m是顾客想要的商品种类数。
- 本算法的时间复杂度为 O(n + m),其中
-
空间复杂度:
- 使用了两个
HashMap,空间复杂度为 O(n + m)。
- 使用了两个
学习建议
-
理解数据结构:
- 深入理解
HashMap的工作原理及其常用方法。 - 掌握其他数据结构(如
ArrayList,LinkedList,Set等)的使用场景。
- 深入理解
-
练习字符串操作:
- 多做字符串相关的练习题,熟悉字符串的各种操作方法。
- 理解字符串与字符数组之间的转换。
-
分析问题:
- 学会分析问题的本质,找到问题的关键点。
- 尝试将复杂问题分解成更小的子问题。
-
动手实践:
- 多写代码,尝试不同的算法和数据结构。
- 尝试自己实现算法,并进行调试和优化。
-
学习资源:
- 阅读经典算法