题目:
leetcode.cn/problems/de…
算法:
方法一:堆+懒删除
总体思路:
- HighestRated要根据cusine找到评分最高的菜单,这显然是用堆来实现最好,每个cuisine使用一个堆。
- 另外ChangeRating函数要求按food修改评分,修改之后堆如何重新平衡是需要解决的问题。
我们使用懒删除来解决这个问题:用一个map[food]newRating记录food最新的评分,每次ChangeRating时更新map[food]newRating,并且往heap中插入一条最新的评分pair{food, newRating}。这样heap中对于food维护了新旧两条数据,当堆顶的数据的rating等于map[food]中的分数时,才是最新的数据,不等则出heap即可。
import "container/heap"
type FoodRatings struct {
cr map[string]*hp
fr map[string]*pair
}
func Constructor(foods []string, cuisines []string, ratings []int) FoodRatings {
foodRatings := FoodRatings{
cr: make(map[string]*hp),
fr: make(map[string]*pair),
}
for i := range foods {
h, ok := foodRatings.cr[cuisines[i]]
if !ok {
h = &hp{}
foodRatings.cr[cuisines[i]] = h
}
heap.Push(h, pair{food:foods[i], rating:ratings[i]})
foodRatings.fr[foods[i]] = &pair{cuisine:cuisines[i], rating:ratings[i]}
}
return foodRatings
}
func (this *FoodRatings) ChangeRating(food string, newRating int) {
this.fr[food].rating = newRating
h := this.cr[this.fr[food].cuisine]
heap.Push(h, pair{food:food, rating:newRating})
}
func (this *FoodRatings) HighestRated(cuisine string) string {
h := this.cr[cuisine]
for (*h).Len() > 0 && (*h)[0].rating != this.fr[(*h)[0].food].rating{
heap.Pop(h)
}
return (*h)[0].food
}
type pair struct {
food string
rating int
cuisine string
}
type hp []pair
func (h hp) Less(i, j int) bool {
if h[i].rating == h[j].rating {
return h[i].food < h[j].food
}
return h[i].rating > h[j].rating
}
func (h hp) Len() int {
return len(h)
}
func (h hp) Swap(i, j int) {
h[i], h[j] = h[j], h[i]
}
func(h *hp) Push(x interface{}) {
*h = append(*h, x.(pair))
}
func(h *hp) Pop() interface{} {
old := *h
n := len(old)
x := old[n - 1]
*h = old[:n -1]
return x
}
/**
* Your FoodRatings object will be instantiated and called as such:
* obj := Constructor(foods, cuisines, ratings);
* obj.ChangeRating(food,newRating);
* param_2 := obj.HighestRated(cuisine);
*/