Solving Leetcode Interviews in Seconds with AI: Design a Food Rating System
Introduction
In this blog post, we will explore how to solve the LeetCode problem "2353" using AI. LeetCode is a popular platform for preparing for coding interviews, and with the help of AI tools like Chatmagic, we can generate solutions quickly and efficiently - helping you pass the interviews and get the job offer without having to study for months.
Problem Statement
Design a food rating system that can do the following: Modify the rating of a food item listed in the system. Return the highest-rated food item for a type of cuisine in the system. Implement the FoodRatings class: FoodRatings(String[] foods, String[] cuisines, int[] ratings) Initializes the system. The food items are described by foods, cuisines and ratings, all of which have a length of n. foods[i] is the name of the ith food, cuisines[i] is the type of cuisine of the ith food, and ratings[i] is the initial rating of the ith food. void changeRating(String food, int newRating) Changes the rating of the food item with the name food. String highestRated(String cuisine) Returns the name of the food item that has the highest rating for the given type of cuisine. If there is a tie, return the item with the lexicographically smaller name. Note that a string x is lexicographically smaller than string y if x comes before y in dictionary order, that is, either x is a prefix of y, or if i is the first position such that x[i] != y[i], then x[i] comes before y[i] in alphabetic order. Example 1: Input ["FoodRatings", "highestRated", "highestRated", "changeRating", "highestRated", "changeRating", "highestRated"] [[["kimchi", "miso", "sushi", "moussaka", "ramen", "bulgogi"], ["korean", "japanese", "japanese", "greek", "japanese", "korean"], [9, 12, 8, 15, 14, 7]], ["korean"], ["japanese"], ["sushi", 16], ["japanese"], ["ramen", 16], ["japanese"]] Output [null, "kimchi", "ramen", null, "sushi", null, "ramen"] Explanation FoodRatings foodRatings = new FoodRatings(["kimchi", "miso", "sushi", "moussaka", "ramen", "bulgogi"], ["korean", "japanese", "japanese", "greek", "japanese", "korean"], [9, 12, 8, 15, 14, 7]); foodRatings.highestRated("korean"); // return "kimchi" // "kimchi" is the highest rated korean food with a rating of 9. foodRatings.highestRated("japanese"); // return "ramen" // "ramen" is the highest rated japanese food with a rating of 14. foodRatings.changeRating("sushi", 16); // "sushi" now has a rating of 16. foodRatings.highestRated("japanese"); // return "sushi" // "sushi" is the highest rated japanese food with a rating of 16. foodRatings.changeRating("ramen", 16); // "ramen" now has a rating of 16. foodRatings.highestRated("japanese"); // return "ramen" // Both "sushi" and "ramen" have a rating of 16. // However, "ramen" is lexicographically smaller than "sushi". Constraints: 1 <= n <= 2 104 n == foods.length == cuisines.length == ratings.length 1 <= foods[i].length, cuisines[i].length <= 10 foods[i], cuisines[i] consist of lowercase English letters. 1 <= ratings[i] <= 108 All the strings in foods are distinct. food will be the name of a food item in the system across all calls to changeRating. cuisine will be a type of cuisine of at least one food item in the system across all calls to highestRated. At most 2 104 calls in total will be made to changeRating and highestRated.
Explanation
Here's a breakdown of the approach and the Python code:
- High-Level Approach:
- Use dictionaries to store mappings for food to cuisine and food to rating for efficient lookups.
- Use a sorted set (using a custom comparison to handle rating and lexicographical order) for each cuisine to maintain the food items in sorted order based on rating and name.
- Complexity:
- Time Complexity:
FoodRatings: O(N log N),changeRating: O(log N),highestRated: O(1) where N is the number of foods. - Space Complexity: O(N)
- Time Complexity:
- Python Code:
Code
from sortedcontainers import SortedSet
class FoodRatings:
def __init__(self, foods: list[str], cuisines: list[str], ratings: list[int]):
self.food_to_cuisine = {}
self.food_to_rating = {}
self.cuisine_to_foods = {}
for i in range(len(foods)):
food = foods[i]
cuisine = cuisines[i]
rating = ratings[i]
self.food_to_cuisine[food] = cuisine
self.food_to_rating[food] = rating
if cuisine not in self.cuisine_to_foods:
self.cuisine_to_foods[cuisine] = SortedSet()
self.cuisine_to_foods[cuisine].add((-rating, food)) # Store negative rating for sortedset to work correctly
def changeRating(self, food: str, newRating: int) -> None:
cuisine = self.food_to_cuisine[food]
old_rating = self.food_to_rating[food]
self.cuisine_to_foods[cuisine].remove((-old_rating, food))
self.food_to_rating[food] = newRating
self.cuisine_to_foods[cuisine].add((-newRating, food))
def highestRated(self, cuisine: str) -> str:
return self.cuisine_to_foods[cuisine][0][1]