Leetcode2353:设计食物评分系统

题目描述:

设计一个支持下述操作的食物评分系统:

  • 修改 系统中列出的某种食物的评分。
  • 返回系统中某一类烹饪方式下评分最高的食物。

实现 FoodRatings 类:

  • FoodRatings(String[] foods, String[] cuisines, int[] ratings) 初始化系统。食物由 foodscuisines 和 ratings 描述,长度均为 n 。
    • foods[i] 是第 i 种食物的名字。
    • cuisines[i] 是第 i 种食物的烹饪方式。
    • ratings[i] 是第 i 种食物的最初评分。
  • void changeRating(String food, int newRating) 修改名字为 food 的食物的评分。
  • String highestRated(String cuisine) 返回指定烹饪方式 cuisine 下评分最高的食物的名字。如果存在并列,返回 字典序较小 的名字。

注意,字符串 x 的字典序比字符串 y 更小的前提是:x 在字典中出现的位置在 y 之前,也就是说,要么 x 是 y 的前缀,或者在满足 x[i] != y[i] 的第一个位置 i 处,x[i] 在字母表中出现的位置在 y[i] 之前。

代码思路:

1. 初始化 (__init__ 方法)

  • 参数:
    • foods: 食物名称的列表。
    • cuisines: 与食物列表对应的菜系列表。
    • ratings: 与食物列表对应的评分列表。
  • 属性:
    • self.cuisines: 使用 defaultdict(list) 创建一个字典,键是菜系名称,值是一个列表(实际用作堆)。堆中存储的是元组,元组的第一个元素是评分的相反数(为了使用最大堆的特性),第二个元素是食物名称。
    • self.foods: 一个字典,键是食物名称,值是一个列表,包含两个元素:菜系名称和评分。
  • 实现步骤:
    • 遍历 foods 列表,同时获取对应的 cuisine 和 rating
    • 将 [-rating, food] 元组添加到对应菜系的堆中(self.cuisines[cuisine])。
    • 将食物名称、菜系和评分以列表形式存储到 self.foods 字典中。

2. 修改评分 (changeRating 方法)

  • 参数:
    • food: 需要修改评分的食物名称。
    • newRating: 新的评分。
  • 实现步骤:
    • 更新 self.foods 字典中对应食物的评分。
    • 获取该食物所属菜系。
    • 将新的评分(以 [-newRating, food] 形式)添加到对应菜系的堆中。注意这里没有删除旧的评分,因为堆不支持直接删除元素。不过,由于堆顶始终是当前最高评分的相反数(或更新后的最高评分),所以这种添加方式不会影响查询最高评分的正确性。

3. 查询最高评分食物 (highestRated 方法)

  • 参数:
    • cuisine: 需要查询的菜系名称。
  • 返回值:
    • 返回该菜系中评分最高的食物名称。
  • 实现步骤:
    • 获取对应菜系的堆。
    • 使用堆的特性,堆顶元素总是评分最高的相反数(因此我们需要取相反数以获取实际评分)。
    • 但是,由于可能存在评分更新后堆顶元素未同步更新的情况,我们需要检查堆顶元素的实际评分是否与 self.foods 中存储的评分一致。
    • 如果不一致,说明堆顶元素是过期的,使用 heappop 将其弹出,并继续检查下一个堆顶元素,直到找到实际评分与堆顶元素表示的评分一致的食物。
    • 返回最高评分的食物名称。

代码实现:

class FoodRatings:
    def __init__(self, foods: List[str], cuisines: List[str], ratings: List[int]):
        self.cuisines = defaultdict(list) # 按类别建立堆
        self.foods = {} # 存每种食物的类别和分数
        for i, food in enumerate(foods):
            cuisine, rating = cuisines[i], ratings[i]
            
            heappush(self.cuisines[cuisine], [-rating, food])
            self.foods[food] = [cuisine, rating]

    def changeRating(self, food: str, newRating: int) -> None:
        self.foods[food][1] = newRating # 更新分数
        cuisine = self.foods[food][0]
        
        # 把更新的分数扔进堆,不需要把旧的找出来删掉
        heappush(self.cuisines[cuisine], [-newRating, food])

    def highestRated(self, cuisine: str) -> str:
        cuisine = self.cuisines[cuisine]
        # 堆顶就是最大值
        # 但是如果和实际分数不一样说明是过期的信息,弹走
        while -cuisine[0][0] != self.foods[cuisine[0][1]][1]:
            heappop(cuisine)
        return cuisine[0][1]

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值