饭馆菜品选择问题|豆包MarsCode AI刷题;

68 阅读3分钟

问题描述

小C来到了一家饭馆,这里共有 n 道菜,第 i 道菜的价格为 a_i。其中一些菜中含有蘑菇,s_i 代表第 ii 道菜是否含有蘑菇。如果 s_i = '1',那么第 i 道菜含有蘑菇,否则没有。

小C希望点 k 道菜,且希望总价格尽可能低。由于她不喜欢蘑菇,她希望所点的菜中最多只有 m 道菜含有蘑菇。小C想知道在满足条件的情况下能选出的最小总价格是多少。如果无法按照要求选择菜品,则输出-1

测试样例

样例1:

输入:s = "001", a = [10, 20, 30], m = 1, k = 2
输出:30

样例2:

输入:s = "111", a = [10, 20, 30], m = 1, k = 2
输出:-1

样例3:

输入:s = "0101", a = [5, 15, 10, 20], m = 2, k = 3
输出:30

题目分析

  1. 菜品总数不足

    • 如果不含蘑菇和含蘑菇的菜品总数小于k,则无法选择足够的菜品,直接返回-1
  2. 蘑菇菜品数量限制

    • 在遍历可能的含有蘑菇的菜品数量x时,x的范围是从0m,确保不超过最多可以选择的含有蘑菇的菜品数量。
  3. 选择的菜品数量

    • 在选择菜品时,确保选择的含有蘑菇的菜品数量x不超过mushroomDishes的大小,且选择的不含蘑菇的菜品数量k - x不超过nonMushroomDishes的大小。

代码实现

import java.util.*;

public class Main {
    public static int solution(String s,int[] a, int m,int k ) {
        // 分别存储含蘑菇的菜品和不含蘑菇的菜品
List<Integer> mushroomDishes = new ArrayList<>();
        List<Integer> nonMushroomDishes = new ArrayList<>();
        int n = s.length();
        for (int i = 0; i < n; i++) {
            if (s.charAt(i) == '1') {
                mushroomDishes.add(a[i]);
            } else {
                nonMushroomDishes.add(a[i]);
            }
        }

        // 排序,确保选择最便宜的菜品
Collections.sort(mushroomDishes);
        Collections.sort(nonMushroomDishes);

        // 如果总的菜品数不足k,直接返回-1
if (mushroomDishes.size() + nonMushroomDishes.size() < k) {
            return -1;
        }

        // 找最小的总价格
int result = Integer.MAX_VALUE;

        // 遍历可能的蘑菇菜品数量x,0 <= x <= m
for (int x = 0; x <= m; x++) {
            // x表示选择的蘑菇菜品数量
if (x > mushroomDishes.size()) {
                break;  // 蘑菇菜品数量超过了可选的数量,跳出循环
}

            // 如果剩余的需要选择的不含蘑菇的菜品数量大于其数量,也跳出
if (k - x > nonMushroomDishes.size()) {
                continue;
            }

            // 计算当前选择菜品的总价格
int sum = 0;

            // 选择x个蘑菇菜品
for (int i = 0; i < x; i++) {
                sum += mushroomDishes.get(i);
            }

            // 选择k - x个非蘑菇菜品
for (int i = 0; i < k - x; i++) {
                sum += nonMushroomDishes.get(i);
            }

            // 更新最小价格
result = Math.min(result, sum);
        }

        // 如果无法找到符合条件的选择,返回-1
return result == Integer.MAX_VALUE ? -1 : result;
    }

代码逻辑分析

  1. 初始化两个列表

    • mushroomDishes:用于存储含有蘑菇的菜品的价格。
    • nonMushroomDishes:用于存储不含蘑菇的菜品的价格。
  2. 填充列表

    • 遍历字符串s,根据每个字符('1'表示含有蘑菇,'0'表示不含蘑菇)将对应的菜品价格添加到相应的列表中。
  3. 对列表进行排序

    • 对两个列表进行排序,以确保选择最便宜的菜品。

时间复杂度分析

  • 初始化和排序:O(n) + O(nlogn) = O(nlogn)(假设n是菜品总数,且m和k都小于等于n)
  • 遍历和计算:O(m * k)(对于每个x值,都需要计算k个元素的总和)

因此,整体的时间复杂度是O(nlogn) + O(m * k)。在最坏的情况下,如果m接近n,时间复杂度可以近似为O(n^2)。然而,由于m通常远小于n,所以O(nlogn)是主导因素。

总结

使用豆包MarsCode AI工具后,我的解题速度得到了显著提升,同时在知识整理和错题分析方面也有了长足的进步。我计划继续利用AI的功能结合传统学习资源,来加强我的算法基础,并挑战更高难度的题目。

希望我的这些经验能够对其他初学者有所启发和帮助。让我们共同享受学习算法带来的乐趣,并在这个过程中不断进步和成长!