|
| 1 | +import collections |
| 2 | +import heapq |
| 3 | +from dataclasses import dataclass, field |
| 4 | +from typing import List |
| 5 | + |
| 6 | + |
| 7 | +@dataclass(order=True) |
| 8 | +class Food: |
| 9 | + """Item stored in the priority queue.""" |
| 10 | + |
| 11 | + rating: int = field(compare=True) |
| 12 | + food: str = field(compare=True) |
| 13 | + cuisine: str = field(compare=False) |
| 14 | + |
| 15 | + |
| 16 | +class FoodRatings: |
| 17 | + """ |
| 18 | + Design a food rating system that can do the following: |
| 19 | + - Modify the rating of a food item listed in the system. |
| 20 | + - Return the highest-rated food item for a type of cuisine in the system. |
| 21 | + |
| 22 | + Implement the FoodRatings class: |
| 23 | + - FoodRatings(String[] foods, String[] cuisines, int[] ratings) Initializes the |
| 24 | + system. The food items are described by foods, cuisines and ratings, all of which |
| 25 | + have a length of n. |
| 26 | + - foods[i] is the name of the ith food, |
| 27 | + - cuisines[i] is the type of cuisine of the ith food, and |
| 28 | + - ratings[i] is the initial rating of the ith food. |
| 29 | + - void changeRating(String food, int newRating) Changes the rating of the food item |
| 30 | + with the name food. |
| 31 | + - String highestRated(String cuisine) Returns the name of the food item that has the |
| 32 | + highest rating for the given type of cuisine. If there is a tie, return the item |
| 33 | + with the lexicographically smaller name. |
| 34 | + |
| 35 | + Note that a string x is lexicographically smaller than string y if x comes before y |
| 36 | + in dictionary order, that is, either x is a prefix of y, or if i is the first |
| 37 | + position such that x[i] != y[i], then x[i] comes before y[i] in alphabetic order. |
| 38 | + """ |
| 39 | + |
| 40 | + def __init__(self, foods: List[str], cuisines: List[str], ratings: List[int]): |
| 41 | + self.food_to_cuisine = {} |
| 42 | + self.food_to_rating = {} |
| 43 | + self.cuisine_to_max_food = collections.defaultdict(list) |
| 44 | + |
| 45 | + for f, c, r in zip(foods, cuisines, ratings, strict=False): |
| 46 | + self.food_to_cuisine[f] = c |
| 47 | + self.food_to_rating[f] = -r |
| 48 | + heapq.heappush(self.cuisine_to_max_food[c], Food(-r, f, c)) |
| 49 | + |
| 50 | + def changeRating(self, food: str, newRating: int) -> None: |
| 51 | + # Update food_to_rating |
| 52 | + self.food_to_rating[food] = -newRating |
| 53 | + |
| 54 | + # Insert the new food element in the priority queue |
| 55 | + cuisine = self.food_to_cuisine[food] |
| 56 | + heapq.heappush( |
| 57 | + self.cuisine_to_max_food[cuisine], Food(-newRating, food, cuisine) |
| 58 | + ) |
| 59 | + |
| 60 | + def highestRated(self, cuisine: str) -> str: |
| 61 | + # Get the highest rated food of |
| 62 | + max_food = self.cuisine_to_max_food[cuisine][0] |
| 63 | + |
| 64 | + while self.food_to_rating[max_food.food] != max_food.rating: |
| 65 | + heapq.heappop(self.cuisine_to_max_food[cuisine]) |
| 66 | + max_food = self.cuisine_to_max_food[cuisine][0] |
| 67 | + |
| 68 | + return max_food.food |
0 commit comments