【算法】小C的菜品选择:每日一问之今天吃什么!🍽️

197 阅读3分钟

算法相对来说一直是我这个前端崽的薄弱项,趁有时间正好可以刷掘金的AI刷题。看到一个有意思的题目:饭馆菜品选择问题,作为一个资深吃货,这不就来了动力!让我们一起来为小C选出花最少的钱,吃最心头好的菜。🍽️

image.png

问题描述

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

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

解题思路

唔..总的来说就是小C想花最少的钱吃最好的菜。但是因为她不爱吃蘑菇,所以我们得优先考虑没有蘑菇的菜品(你就宠她吧🍜)。整理思路如下:

  1. 分类菜品:将菜品分为含蘑菇和不含蘑菇两类。
  2. 排序:分别对这两类菜品的价格进行排序,以便于选择最便宜的菜品。
  3. 组合选择:遍历非含蘑菇菜品,并对比蘑菇菜品价格,计算出最小总价格,确保总菜品数为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不爱吃蘑菇,所以选择了九宫格的主题是超级马里奥。左上方是计算结果,数字输入框分别是可接受的蘑菇最大数、菜品数,点击按钮计算最小总价格,并且回显所选中的菜品。(这样就一目了然啦)

image.png

动画效果

既然为小C选出了菜品,那不妨加点动画效果显得更生趣一点,于是想到马里奥顶砖块吃到蘑菇的动画。(Mac不知道怎么录屏..)

image.png

今天吃什么

到这里不爱吃蘑菇的小C已经做出了她的菜品选择,所以你又打算今天吃什么呢?如果还没主意的话那就来摇一摇吧!🍜

好吃的店就会希望它能一直都在呢👾

image.png

image.png