Skip to main content
Back to problems
#2353
Medium Algorithms

Design a food rating system

Array Hash Table String Design Heap (Priority Queue) Ordered Set
52.9% acceptance
Jan 13, 2026
1958
328
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.

Solution

Rust
Time O(n log n)
Space O(n)
LeetCode
solution.rs
* impl FoodRatings {

 *     fn new(foods: Vec<String>, cuisines: Vec<String>, ratings: Vec<i32>) -> Self {

 *     }

 *     fn change_rating(&self, food: String, new_rating: i32) {

 *     }

 *     fn highest_rated(&self, cuisine: String) -> String {

 *     }
 * }
 */

/**
 * Your FoodRatings object will be instantiated and called as such:
 * let obj = FoodRatings::new(foods, cuisines, ratings);
 * obj.change_rating(food, newRating);
 * let ret_2: String = obj.highest_rated(cuisine);
 */

use std::collections::{HashMap, BTreeSet};
use std::cmp::Reverse;

pub struct FoodRatings {
  food_cuisine: HashMap<String, String>,
  food_rating: HashMap<String, i32>,
  cuisine_foods: HashMap<String, BTreeSet<(Reverse<i32>, String)>>,
}

impl FoodRatings {
  pub fn new(foods: Vec<String>, cuisines: Vec<String>, ratings: Vec<i32>) -> Self {
    let mut fr = FoodRatings {
      food_cuisine: HashMap::new(),
      food_rating: HashMap::new(),
      cuisine_foods: HashMap::new(),
    };
    for i in 0..foods.len() {
      let food = foods[i].clone();
      let cuisine = cuisines[i].clone();
      let rating = ratings[i];
      fr.food_cuisine.insert(food.clone(), cuisine.clone());
      fr.food_rating.insert(food.clone(), rating);
      fr.cuisine_foods.entry(cuisine).or_default().insert((Reverse(rating), food));
    }
    fr
  }

  pub fn change_rating(&mut self, food: String, new_rating: i32) {
    let cuisine = self.food_cuisine[&food].clone();
    let old_rating = self.food_rating[&food];
    let set = self.cuisine_foods.get_mut(&cuisine).unwrap();
    set.remove(&(Reverse(old_rating), food.clone()));
    set.insert((Reverse(new_rating), food.clone()));
    self.food_rating.insert(food, new_rating);
  }

  pub fn highest_rated(&self, cuisine: String) -> String {
    self.cuisine_foods[&cuisine].iter().next().unwrap().1.clone()
  }
}