AI刷题154 小C点菜问题| 豆包MarsCode AI刷题

117 阅读4分钟

题目解析

这是一道与数组和哈希表相关的简单统计问题。题目要求计算一个人最多可以点多少道价格相同的菜,并且单价不能超过一个上限 m。具体来说:

  1. 输入

    • 一个整数 m,表示单道菜的价格不能超过的上限;
    • 一个数组 w[],表示每道菜的价格。
  2. 目标

    • 找到满足条件的最多的相同价格的菜数,即统计价格不超过 m 的菜中,出现次数最多的价格。
  3. 约束

    • 单价必须小于等于 m;
    • 只考虑相同价格的菜。

解题思路

要解决这个问题,可以按照以下步骤分解:

  1. 筛选价格符合条件的菜

    • 遍历数组 w[],统计单价不超过 mm 的菜,并记录它们的出现次数。
  2. 统计价格出现频率

    • 使用哈希表(HashMap),以菜品价格为键,频率为值。
  3. 找出最高频率

    • 遍历哈希表的键值对,找到价格 ≤m≤m 中最大频率的值。
  4. 输出结果

    • 返回最大频率。

这种解法的核心是利用哈希表的统计能力,以 O(n) 的时间复杂度快速完成频率统计。算法具有高效性和鲁棒性。


图解思路

举例:
若菜品价格数组为 w=[2,3,3,6,6,6,9,9,23],且 m=6。

  1. 首先,筛选出价格 ≤6 的菜:2,3,3,6,6,6。

  2. 统计价格出现次数:

    • 价格 2:1 次;
    • 价格 3:2 次;
    • 价格 6:3 次。
  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);
    }
}

代码说明

  1. hashMap.put() 方法

    • 用于更新菜品价格的频率,如果价格已经存在,则累加 1。
  2. getOrDefault() 方法

    • 当 w[i] 不存在于 hashMap 时,默认返回 0。
  3. 遍历 hashMap 的逻辑

    • 通过 entrySet() 遍历每一个价格,检查其是否小于等于 mm,并更新最大频率 price 和对应的菜数 num
  4. 返回结果

    • num 记录最多出现的次数,即最多可以点的菜的数量。

算法复杂度分析

  • 时间复杂度

    1. 遍历数组 w[],时间复杂度为 O(n);
    2. 遍历哈希表的键值对,时间复杂度为 O(k),其中 k 为价格种类数。

    综合来看,时间复杂度约为 O(n)。

  • 空间复杂度: 使用了一个哈希表存储价格频率,空间复杂度为 O(k)。


个人思考与优化

  1. 边界情况

    • 若 w[] 为空,则结果应为 0。
    • 若所有菜的价格都大于 m,则结果也应为 0。
  2. 扩展功能

    • 如果希望知道具体的价格,可以在 HashMap 遍历中保存对应的价格键。
  3. 优化点

    • 若价格种类数 k 远小于数组长度nn,可以进一步优化统计过程。

测试用例分析

提供了以下测试用例,验证了算法的正确性:

  1. 测试用例 1: 输入:m=6,w=[2,3,3,6,6,6,9,9,23]。
    输出:3(最多点 3 道价格为 6 的菜)。
  2. 测试用例 2: 输入:m=4,w=[1,2,4,4,4]。
    输出:3(最多点 3 道价格为 4 的菜)。
  3. 测试用例 3: 输入:m=5,w=[5,5,5,5,6,7,8]。
    输出:4(最多点 4 道价格为 5 的菜)。

总结

通过本题,可以学习到以下内容:

  1. 如何高效地使用哈希表进行频率统计;
  2. 遍历和条件筛选的优化逻辑;
  3. Java 中 HashMap 的常用操作,如 put() 和 getOrDefault()

此外,这种问题的求解思路可以扩展到其他领域,比如文本中单词频率统计等。希望大家通过本文能深入理解问题并掌握类似问题的解决技巧!