算法相对来说一直是我这个前端崽的薄弱项,趁有时间正好可以刷掘金的AI刷题。看到一个有意思的题目:饭馆菜品选择问题,作为一个资深吃货,这不就来了动力!让我们一起来为小C选出花最少的钱,吃最心头好的菜。🍽️
问题描述
小C来到了一家饭馆,这里共有 n 道菜,第 i 道菜的价格为
a_i。其中一些菜中含有蘑菇,s_i代表第 i 道菜是否含有蘑菇。如果s_i = '1',那么第 i 道菜含有蘑菇,否则没有。小C希望点 k 道菜,且希望总价格尽可能低。由于她不喜欢蘑菇,她希望所点的菜中最多只有 m 道菜含有蘑菇。小C想知道在满足条件的情况下能选出的最小总价格是多少。如果无法按照要求选择菜品,则输出
-1。
解题思路
唔..总的来说就是小C想花最少的钱吃最好的菜。但是因为她不爱吃蘑菇,所以我们得优先考虑没有蘑菇的菜品(你就宠她吧🍜)。整理思路如下:
- 分类菜品:将菜品分为含蘑菇和不含蘑菇两类。
- 排序:分别对这两类菜品的价格进行排序,以便于选择最便宜的菜品。
- 组合选择:遍历非含蘑菇菜品,并对比蘑菇菜品价格,计算出最小总价格,确保总菜品数为k。
测试样例
样例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
代码实现
function solution(s: string, a: number[], m: number, k: number): number {
// PLEASE DO NOT MODIFY THE FUNCTION SIGNATURE
// write code here
const mushroomDishes: number[] = []
const nonMushroomDishes: number[] = []
// 分类菜品
for (let i = 0; i < s.length; i++) {
if (s[i] === '1') {
mushroomDishes.push(a[i])
} else {
nonMushroomDishes.push(a[i])
}
}
// 如果无法按照要求选择菜品,则输出-并返回
if (k - m > nonMushroomDishes.length) {
return -1
}
m = Math.min(k, m)
// 排序
mushroomDishes.sort((x, y) => x - y)
nonMushroomDishes.sort((x, y) => x - y)
let count = 0
// 计算菜品价钱
const minPrice = nonMushroomDishes.slice(0, k).reduce((sum, price) => {
if (price > mushroomDishes[k - count - 1]) return sum
count++
return sum + price
}, 0) + mushroomDishes.slice(0, k - count).reduce((sum, price) => sum + price, 0)
return minPrice
}
function main() {
console.log(solution("001", [10, 20, 30], 1, 2) === 30);
console.log(solution("111", [10, 20, 30], 1, 2) === -1);
console.log(solution("0101", [5, 15, 10, 20], 2, 3) === 30);
}
main();
其他完善
以上代码在AI运行结果就全都是打印出true了,but..只是一个代码编译未免有点无聊了。🥱于是我打开了小程序项目,用可视化的方式开启这道算法题。(纯玩 嘿嘿)
页面UI设计
没有灵感没有灵感,于是灵机一动按照稀土掘金的每日抽奖画出了页面。由于小C不爱吃蘑菇,所以选择了九宫格的主题是超级马里奥。左上方是计算结果,数字输入框分别是可接受的蘑菇最大数、菜品数,点击按钮计算最小总价格,并且回显所选中的菜品。(这样就一目了然啦)
动画效果
既然为小C选出了菜品,那不妨加点动画效果显得更生趣一点,于是想到马里奥顶砖块吃到蘑菇的动画。(Mac不知道怎么录屏..)
今天吃什么
到这里不爱吃蘑菇的小C已经做出了她的菜品选择,所以你又打算今天吃什么呢?如果还没主意的话那就来摇一摇吧!🍜
好吃的店就会希望它能一直都在呢👾