给大家分享一下我最近刷的几道题的解析,还有我对ai助手的使用心得,这是第一次给大家分享的刷题解析和经验分享,这个系列预计有六期,今天给大家带来第四期的分享。
今天的题目——超市里的货物架调整
问题描述
在一个超市里,有一个包含 nn 个格子的货物架,每个格子中放有一种商品,商品用小写字母 a 到 z 表示。当顾客进入超市时,他们会依次从第一个格子查找到第 nn 个格子,寻找自己想要购买的商品。如果在某个格子中找到该商品,顾客就会购买它并离开;如果中途遇到一个空格子,或查找完所有格子还没有找到想要的商品,顾客也会离开。
作为超市管理员,你可以在顾客到来之前重新调整商品的顺序,以便尽可能多地出售商品。当第一个顾客进入后,商品位置不能再调整。你需要计算在最优调整下,最多可以卖出多少件商品。输入变量说明:
n:货物架的格子数m:顾客想要购买的商品种类数s:货物架上商品的初始顺序c:顾客想要购买的商品种类
测试样例
样例1:
输入:
n = 3 ,m = 4 ,s = "abc" ,c = "abcd"
输出:3
样例2:
输入:
n = 4 ,m = 2 ,s = "abbc" ,c = "bb"
输出:2
样例3:
输入:
n = 5 ,m = 4 ,s = "bcdea" ,c = "abcd"
输出:4
解决方案
核心思路是按照顾客想要购买的商品顺序,依次去检查货物架上是否存在相应商品,如果存在就将其从货物架表示的列表中移除,并记录销售数量,最后返回总的销售数量。
import java.util.List;
public class Main {
public static int solution(int n, int m, String s, String c) {
// 将货架上的商品转换为列表,方便删除操作
List<Character> shelf = new ArrayList<>();
for (char item : s.toCharArray()) {
shelf.add(item);
}
// 记录卖出的商品数量
int salesCount = 0;
// 遍历顾客需求
for (char item : c.toCharArray()) {
// 检查货架上是否存在该商品
if (shelf.contains(item)) {
// 删除该商品
shelf.remove(Character.valueOf(item));
// 记录卖出的商品数量
salesCount++;
}
}
return salesCount;
}
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);
}
}
代码功能概述
整体思路概述
这段代码旨在解决超市货物架商品调整以最大化销售商品数量的问题。其核心思路是按照顾客想要购买的商品顺序,依次去检查货物架上是否存在相应商品,如果存在就将其从货物架表示的列表中移除,并记录销售数量,最后返回总的销售数量。
代码结构与功能分析
-
数据结构选择与初始化
- 首先创建了一个
ArrayList<Character>类型的列表shelf,用于模拟超市的货物架。通过遍历输入的字符串s(代表货物架上商品的初始顺序),将每个字符(即商品)添加到这个列表中。这样做的好处是,ArrayList提供了方便的元素查找和删除操作方法,便于后续处理。 - 定义了变量
salesCount,用于记录已经卖出的商品数量,初始值设为 0,后续每成功卖出一件商品就会对其进行自增操作。
- 首先创建了一个
-
遍历顾客需求并处理
- 通过一个
for循环遍历输入的字符串c(代表顾客想要购买的商品种类),对于c中的每一个字符(即一种商品),使用shelf.contains(item)方法去检查当前货物架列表shelf中是否存在该商品。这个方法会线性遍历列表去查找匹配元素,时间复杂度在最坏情况下是O(n)(n为列表shelf的长度)。 - 如果在货物架列表中找到了对应的商品,就调用
shelf.remove(Character.valueOf(item))方法将其从列表中移除。这里要注意的是,remove方法会移除列表中第一个匹配的元素,并且在移除元素后,列表后面的元素会向前移动来填补空缺,时间复杂度也是O(n)(因为可能需要移动多个元素)。同时,将salesCount自增 1,表示成功卖出了一件商品。
- 通过一个
-
返回结果
最后,函数返回salesCount,这个值就代表了在给定的货物架初始状态和顾客需求情况下,能够卖出的商品数量。存在的问题与改进建议
-
效率问题
- 目前代码中,每次调用
shelf.contains(item)方法都需要线性遍历列表去查找元素,在顾客需求较多或者货物架商品数量庞大时,效率会比较低。可以考虑使用HashMap<Character, Integer>来预先统计货物架上每种商品的数量,其中键为商品字符,值为该商品在货物架上的剩余数量。这样在检查商品是否存在时,时间复杂度可以降为O(1),只需要通过键去查找对应的值是否大于 0 即可。 - 同样,
shelf.remove(Character.valueOf(item))操作在列表较长时效率不高,因为它涉及到元素的移动。如果采用了前面提到的HashMap来统计商品数量,当确定商品存在且要 “卖出” 时,只需要将对应的商品数量减 1 即可,避免了列表元素的移动操作,能大大提高效率。
- 目前代码中,每次调用
-
逻辑完整性问题
- 当前代码并没有按照题目要求去考虑通过调整商品顺序来实现最大化销售数量这一关键目标。代码只是简单地按照顾客需求顺序去检查和移除货物架上已有的商品,没有尝试对货物架上的商品进行重新排列优化。可以采用类似滑动窗口或者贪心算法的思想,先统计出顾客需求中各商品的数量,然后尝试在货物架上移动窗口或者调整商品顺序,找出能使满足顾客需求最多的一种排列方式,从而真正实现最大化销售商品数量的功能。
-
异常处理缺失
- 代码没有对可能出现的异常情况进行处理,比如传入的参数不符合要求(例如
n、m为负数,或者s、c为空字符串等情况)。在实际应用中,应该添加适当的参数合法性检查,并抛出相应的异常或者返回合适的错误提示信息,增强代码的健壮性。
- 代码没有对可能出现的异常情况进行处理,比如传入的参数不符合要求(例如
改进代码(仅展示关键改进思路)
下面是使用HashMap改进统计商品数量部分的代码:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Main {
public static int solution(int n, int m, String s, String c) {
// 使用HashMap统计货架上每种商品的数量
Map<Character, Integer> shelfMap = new HashMap<>();
for (char item : s.toCharArray()) {
shelfMap.put(item, shelfMap.getOrDefault(item, 0) + 1);
}
// 记录卖出的商品数量
int salesCount = 0;
// 遍历顾客需求
for (char item : c.toCharArray()) {
// 检查货架上是否存在该商品(通过HashMap判断,时间复杂度为O(1))
if (shelfMap.getOrDefault(item, 0) > 0) {
// 减少该商品的数量(模拟卖出,避免了列表元素移除的开销)
shelfMap.put(item, shelfMap.get(item) - 1);
// 记录卖出的商品数量
salesCount++;
}
}
return salesCount;
}
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);
}
}
我对 AI 助手的使用心得
在刷题征途遭遇统计商品数量这类题目时,起初我的解法冗长又低效,纯靠线性遍历检查与计数,一旦数据量庞大,程序便如深陷泥沼,运行缓慢不堪。 直至引入 HashMap 并借助豆包 MarsCode AI 深入剖析,犹如拨云见日。它助我清晰梳理思路,以 HashMap 作为核心“工具”重构代码。遍历初始商品序列时,将每个商品当作键,出现频次设为值存入其中,此后面对顾客需求,检查商品是否在 HashMap 里瞬间完成,时间复杂度从 O(n)锐减至 O(1),大大提升效率。 像处理复杂购物清单与货架数据时,此前方案常超时,优化后不仅快速得出销售数量,还轻松应对海量测试用例。这过程让我深刻领悟数据结构精妙,刷题不再盲目,学会依据场景灵活择取最优策略,编程思维与技巧借此实现质的飞跃。