ETH官方钱包

前往
大廳
主題

LeetCode - 2353. Design a Food Rating System 解題心得

Not In My Back Yard | 2023-06-10 12:00:22 | 巴幣 1000 | 人氣 292

題目連結:


題目意譯:
請設計一個食物評分系統,其可以執行以下操作:
修改系統中的一個食物品項之評分、
回傳在系統中對於特定一種的美食種類而言,最高評分的食物品項為何。

實作類別 FoodRatings:
FoodRatings(String[] foods, String[] cuisines, int[] ratings) 初始化系統。食物品項以 foods 、 cuisines 和 ratings 來描述,三者的長度皆為 n。
    foods[i] 為第 i 個食物的名稱、
    cuisines[i] 為第 i 個食物的美食種類,而
    ratings[i] 為第 i 個食物一開始的評分。    
void changeRating(String food, int newRating) 將名稱為字串 food 的食物品項之評分更改為 newRating。
String highestRated(String cuisine) 回傳對於特定一種的美食種類而言,最高評分的食物品項之名稱。如果有平手的情況發生,則回傳字典序最小的食物名稱。

注意到,一個字串 x 在字典序中小於字串 y,則代表 x 在字典中會先於 y 出現(譯者注:這句話翻成中文就變成廢話了,真有趣)。也就是說,要嘛 x 是 y 的一個前綴,要嘛存在一索引值 i 是第一個滿足 x[i] != y[i] 的索引值,且 x[i] 在字母順序中先於 y[i]。

限制:
1 ≦ n ≦ 2 × 10 ^ 4
n == foods.length == cuisines.length == ratings.length
1 ≦ foods[i].length, cuisines[i].length ≦ 10
foods[i] 、 cuisines[i] 由小寫英文字母組成。
1 ≦ ratings[i] ≦ 10 ^ 8
foods 中字串皆彼此相異。
在呼叫 changeRating 時,food 將保證是系統中某個食物品項的名稱。
在呼叫 highestRated 時,cuisine 將保證是系統中某個美食種類的名稱。
最多呼叫 changeRating 和 highestRated 總計 2 × 10 ^ 4 次。



範例測資:
範例 1:
輸入
["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"]]
輸出
[null, "kimchi", "ramen", null, "sushi", null, "ramen"]
解釋
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"); // 回傳 "kimchi"
                                    // "kimchi" 為 korean 美食中評分最高者,其評分值為 9。
foodRatings.highestRated("japanese"); // 回傳 "ramen"
                                      // "ramen" 為 japanese 美食中評分最高者,其評分值為 9。
foodRatings.changeRating("sushi", 16); // "sushi" 現在評分值為 16。
foodRatings.highestRated("japanese"); // 回傳 "sushi"
                                      // "sushi" 為 japanese 美食中評分最高者,其評分值為 16。
foodRatings.changeRating("ramen", 16); // "ramen" 現在評分值為 16。
foodRatings.highestRated("japanese"); // 回傳 "ramen"
                                      // "sushi" 和 "ramen" 的評分值都是 16。
                                      // 不過,"ramen" 在字典序中是小過 "sushi" 的。
(譯者注:因為實際上是用英文字串來指涉,因此沒有將任何美食種類或是食物名稱給翻譯成中文)。


解題思維:
就是一題大量使用內建字串雜湊(Hash)的模擬題。

首先 FoodRatings() 建構子被呼叫時,我們根據 foods 、 cuisines 、 ratings 來建立以下幾種資訊:
為每種食物品項對應到它們各自屬於的美食種類,所以這裡需要一個雜湊表(Hash Table);
然後每種食物品項再對應到它們各自現在的評分值,所以又需要一個雜湊表;
最後為每一種美食種類建立一個優先佇列(Priority Queue)來隨時更新評分最高的食物品項(因此佇列中每一個位置要放的資訊是食物名稱以及當前評分)。

接著呼叫 changeRating 時,就根據雜湊表把 food 對應到的評分值修改成 newRating 即可。

最後呼叫 highestRated 時,則是需要先判斷給定的美食種類對應的當前佇列之最高評分值的食物品項,它的評分值是不是真的如現在所看到的這個「最高評分值」(因為有可能有先前的 changeRating 更動到其評分值),如果是則回傳該食物名稱;反之則把這個「假」最高移出佇列,然後看下一個最高。而如果又是假最高的就重複此步驟直到遇到一個真的最高。




此次分享到此為止,如有任何更加簡潔的想法或是有說明不清楚之地方,也煩請各位大大撥冗討論。

創作回應

相關創作

更多創作