问题描述
小C来到了一家餐馆,准备点一些菜。
已知该餐馆有 n 道菜,第 i 道菜的售价为 wi。
小C准备点一些价格相同的菜,但小C不会点单价超过 m 的菜。
小C想知道,自己最多可以点多少道菜?
测试样例
样例1:
输入:
m = 6, w = [2, 3, 3, 6, 6, 6, 9, 9, 23]
输出:3
样例2:
输入:
m = 4, w = [1, 2, 4, 4, 4]
输出:3
样例3:
输入:
m = 5, w = [5, 5, 5, 5, 6, 7, 8]
输出:4
思路解析
问题理解
小C想要点一些价格相同的菜,但价格不能超过给定的上限 m。我们需要找出在价格不超过 m 的情况下,最多可以点多少道菜。
数据结构选择
我们可以使用一个数组来存储每道菜的价格。为了快速统计每个价格的菜的数量,可以使用一个哈希表(在Java中可以用 HashMap)来记录每个价格出现的次数。
算法步骤
- 初始化:创建一个
HashMap来记录每个价格出现的次数。 - 遍历数组:遍历菜的价格数组,将每个价格及其出现的次数记录到
HashMap中。 - 统计最大数量:遍历
HashMap,找出价格不超过m的菜中,数量最多的那个价格的数量。
关键点
- 使用
HashMap来统计每个价格出现的次数。 - 遍历
HashMap时,只考虑价格不超过m的菜。
代码详解
import java.util.HashMap;
public class Main {
public static long solution(int m, int[] w) {
// 创建一个 HashMap 来记录每个价格出现的次数
HashMap<Integer, Integer> priceCountMap = new HashMap<>();
// 遍历数组,填充 HashMap
for (int price : w) {
// 如果价格不超过 m,才进行统计
if (price <= m) {
// 更新 HashMap 中该价格的出现次数
priceCountMap.put(price, priceCountMap.getOrDefault(price, 0) + 1);
}
}
// 初始化最大数量
int maxCount = 0;
// 遍历 HashMap,找出价格不超过 m 的菜中,数量最多的那个价格的数量
for (int count : priceCountMap.values()) {
if (count > maxCount) {
maxCount = count;
}
}
return maxCount;
}
public static void main(String[] args) {
System.out.println(solution(6, new int[]{2, 3, 3, 6, 6, 6, 9, 9, 23}) == 3);
System.out.println(solution(4, new int[]{1, 2, 4, 4, 4}) == 3);
System.out.println(solution(5, new int[]{5, 5, 5, 5, 6, 7, 8}) == 4);
}
}
关键步骤解释
-
创建
HashMap:HashMap<Integer, Integer> priceCountMap = new HashMap<>(); -
遍历数组并填充
HashMap:for (int price : w) { if (price <= m) { priceCountMap.put(price, priceCountMap.getOrDefault(price, 0) + 1); } } -
遍历
HashMap找出最大数量:int maxCount = 0; for (int count : priceCountMap.values()) { if (count > maxCount) { maxCount = count; } }
知识总结
1. 数据结构使用
- HashMap:代码中使用了
HashMap<Integer, Integer>(这里假设正确导入了java.util.HashMap)来存储数组w中不同价格(元素值)及其对应的出现次数。其中键(Integer)表示数组中的元素值(价格),值(Integer)表示该元素值在数组中出现的次数。
2. 遍历数组并统计
- 首先通过一个
for-each循环遍历输入的整数数组w:
for(int price : w){
if (price <= m) {
priceCountMap.put(price, priceCountMap.getOrDefault(price,0 )+1);
}
}
在循环中,对于每个元素 price,先判断其是否小于等于给定的整数 m。如果满足条件,就通过 HashMap 的 put 方法来更新该价格在 priceCountMap 中的出现次数。这里使用了 getOrDefault 方法,如果键 price 不存在于 priceCountMap 中,就返回默认值 0,然后再加 1 来记录该价格的出现次数;如果键已经存在,就获取其当前的出现次数并加 1。
3. 找出最大出现次数
- 接着,通过另一个
for-each循环遍历priceCountMap的值(即各个价格的出现次数):
for(int count:priceCountMap.values()){
if (count > maxCount) {
maxCount = count;
}
}
在这个循环中,比较每个出现次数 count 和当前记录的最大出现次数 maxCount,如果 count 大于 maxCount,就更新 maxCount 的值。
4. 返回结果
- 最后,方法返回
maxCount,也就是数组w中值小于等于m的元素里出现次数最多的那个元素的出现次数。
代码可能的应用场景
- 这种代码结构可以用于分析一组数据(如商品价格、学生成绩等)中,在满足一定条件(如价格小于等于某个预算、成绩在某个范围内等)下,出现最频繁的数据值的情况。例如,在一个商店的销售记录中,可以找出价格在某个预算范围内最畅销的商品的销售频次;或者在学生考试成绩统计中,找出某个分数段内出现次数最多的成绩等。
学习计划
-
制定刷题计划
- 确定目标和范围:如果是学习数据结构和算法相关内容,可以根据不同的主题(如排序、搜索、统计等)来划分刷题范围。例如,针对本题涉及的统计数组中元素关系的类型,可以集中刷一批类似的题目。可以从简单到复杂,先从基础的数组遍历和统计题目开始,再到像本题这样有一定逻辑复杂度的题目。
- 安排时间:每天安排固定的时间用于刷题,比如每天 1 - 2 小时。可以将时间分成两部分,一部分用于新题目的练习,另一部分用于复习和总结之前做过的题目。在使用 MarsCode AI 刷题时,可以根据它提供的难度分级和题目类型分类来合理安排每个阶段的刷题量。
工具运用
-
结合 AI 刷题与其他学习资源
-
代码调试工具:结合代码调试工具(如 Java 中的调试器)和 MarsCode AI。当代码出现问题时,在 MarsCode AI 中分析错误信息后,可以使用调试工具来逐步执行代码,查看变量的值和程序的执行流程,更深入地理解代码的问题所在,尤其是对于像本题这种有一定逻辑复杂度的代码。
-