题目解析
这是一道与数组和哈希表相关的简单统计问题。题目要求计算一个人最多可以点多少道价格相同的菜,并且单价不能超过一个上限 m。具体来说:
-
输入:
- 一个整数 m,表示单道菜的价格不能超过的上限;
- 一个数组 w[],表示每道菜的价格。
-
目标:
- 找到满足条件的最多的相同价格的菜数,即统计价格不超过 m 的菜中,出现次数最多的价格。
-
约束:
- 单价必须小于等于 m;
- 只考虑相同价格的菜。
解题思路
要解决这个问题,可以按照以下步骤分解:
-
筛选价格符合条件的菜:
- 遍历数组 w[],统计单价不超过 mm 的菜,并记录它们的出现次数。
-
统计价格出现频率:
- 使用哈希表(
HashMap),以菜品价格为键,频率为值。
- 使用哈希表(
-
找出最高频率:
- 遍历哈希表的键值对,找到价格 ≤m≤m 中最大频率的值。
-
输出结果:
- 返回最大频率。
这种解法的核心是利用哈希表的统计能力,以 O(n) 的时间复杂度快速完成频率统计。算法具有高效性和鲁棒性。
图解思路
举例:
若菜品价格数组为 w=[2,3,3,6,6,6,9,9,23],且 m=6。
-
首先,筛选出价格 ≤6 的菜:2,3,3,6,6,6。
-
统计价格出现次数:
- 价格 2:1 次;
- 价格 3:2 次;
- 价格 6:3 次。
-
找出出现次数最多的价格(满足 ≤m):价格 6,出现 3 次。
因此,最多可以点 3 道价格相同的菜。
代码详解
以下是给出的 Java 实现代码:
import java.util.HashMap;
import java.util.Map;
public class Main {
public static long solution(int m, int[] w) {
// 定义变量
int num = 0; // 记录最多可以点的菜数
int price = 0; // 记录最大频率
// 使用 HashMap 统计每种价格的数量
Map<Integer,Integer> hashMap = new HashMap<Integer,Integer>();
for(int i = 0; i < w.length; i++){
hashMap.put(w[i], hashMap.getOrDefault(w[i], 0) + 1);
}
// 遍历 HashMap,找出符合条件的最大频率
for(Map.Entry<Integer, Integer> entry : hashMap.entrySet()){
if(entry.getKey() <= m){ // 价格不超过 m
if(price < hashMap.get(entry.getKey())){
price = hashMap.get(entry.getKey());
num = hashMap.get(entry.getKey());
}
}
}
return num; // 返回最多的菜数
}
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.put()方法:- 用于更新菜品价格的频率,如果价格已经存在,则累加 1。
-
getOrDefault()方法:- 当
w[i]不存在于hashMap时,默认返回 0。
- 当
-
遍历
hashMap的逻辑:- 通过
entrySet()遍历每一个价格,检查其是否小于等于 mm,并更新最大频率price和对应的菜数num。
- 通过
-
返回结果:
num记录最多出现的次数,即最多可以点的菜的数量。
算法复杂度分析
-
时间复杂度:
- 遍历数组 w[],时间复杂度为 O(n);
- 遍历哈希表的键值对,时间复杂度为 O(k),其中 k 为价格种类数。
综合来看,时间复杂度约为 O(n)。
-
空间复杂度: 使用了一个哈希表存储价格频率,空间复杂度为 O(k)。
个人思考与优化
-
边界情况:
- 若 w[] 为空,则结果应为 0。
- 若所有菜的价格都大于 m,则结果也应为 0。
-
扩展功能:
- 如果希望知道具体的价格,可以在
HashMap遍历中保存对应的价格键。
- 如果希望知道具体的价格,可以在
-
优化点:
- 若价格种类数 k 远小于数组长度nn,可以进一步优化统计过程。
测试用例分析
提供了以下测试用例,验证了算法的正确性:
- 测试用例 1: 输入:m=6,w=[2,3,3,6,6,6,9,9,23]。
输出:3(最多点 3 道价格为 6 的菜)。 - 测试用例 2: 输入:m=4,w=[1,2,4,4,4]。
输出:3(最多点 3 道价格为 4 的菜)。 - 测试用例 3: 输入:m=5,w=[5,5,5,5,6,7,8]。
输出:4(最多点 4 道价格为 5 的菜)。
总结
通过本题,可以学习到以下内容:
- 如何高效地使用哈希表进行频率统计;
- 遍历和条件筛选的优化逻辑;
- Java 中
HashMap的常用操作,如put()和getOrDefault()。
此外,这种问题的求解思路可以扩展到其他领域,比如文本中单词频率统计等。希望大家通过本文能深入理解问题并掌握类似问题的解决技巧!