问题描述
小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
题目分析
-
菜品总数不足:
- 如果不含蘑菇和含蘑菇的菜品总数小于
k,则无法选择足够的菜品,直接返回-1。
- 如果不含蘑菇和含蘑菇的菜品总数小于
-
蘑菇菜品数量限制:
- 在遍历可能的含有蘑菇的菜品数量
x时,x的范围是从0到m,确保不超过最多可以选择的含有蘑菇的菜品数量。
- 在遍历可能的含有蘑菇的菜品数量
-
选择的菜品数量:
- 在选择菜品时,确保选择的含有蘑菇的菜品数量
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;
}
代码逻辑分析
-
初始化两个列表:
mushroomDishes:用于存储含有蘑菇的菜品的价格。nonMushroomDishes:用于存储不含蘑菇的菜品的价格。
-
填充列表:
- 遍历字符串
s,根据每个字符('1'表示含有蘑菇,'0'表示不含蘑菇)将对应的菜品价格添加到相应的列表中。
- 遍历字符串
-
对列表进行排序:
- 对两个列表进行排序,以确保选择最便宜的菜品。
时间复杂度分析
- 初始化和排序: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的功能结合传统学习资源,来加强我的算法基础,并挑战更高难度的题目。
希望我的这些经验能够对其他初学者有所启发和帮助。让我们共同享受学习算法带来的乐趣,并在这个过程中不断进步和成长!