1333. 餐厅过滤器

题目描述:

给你一个餐馆信息数组 restaurants,其中  restaurants[i] = [idi, ratingi, veganFriendlyi, pricei, distancei]。你必须使用以下三个过滤器来过滤这些餐馆信息。

其中素食者友好过滤器 veganFriendly 的值可以为 true 或者 false,如果为 true 就意味着你应该只包括 veganFriendlyi 为 true 的餐馆,为 false 则意味着可以包括任何餐馆。此外,我们还有最大价格 maxPrice 和最大距离 maxDistance 两个过滤器,它们分别考虑餐厅的价格因素和距离因素的最大值。

过滤后返回餐馆的 id,按照 rating 从高到低排序。如果 rating 相同,那么按 id 从高到低排序。简单起见, veganFriendlyi 和 veganFriendly 为 true 时取值为 1,为 false 时,取值为 0 。

测试用例:

示例 1:

输入:restaurants = [[1,4,1,40,10],[2,8,0,50,5],[3,8,1,30,4],[4,10,0,10,3],[5,1,1,15,1]], veganFriendly = 1, maxPrice = 50, maxDistance = 10
输出:[3,1,5] 
解释: 
这些餐馆为:
餐馆 1 [id=1, rating=4, veganFriendly=1, price=40, distance=10]
餐馆 2 [id=2, rating=8, veganFriendly=0, price=50, distance=5]
餐馆 3 [id=3, rating=8, veganFriendly=1, price=30, distance=4]
餐馆 4 [id=4, rating=10, veganFriendly=0, price=10, distance=3]
餐馆 5 [id=5, rating=1, veganFriendly=1, price=15, distance=1] 
在按照 veganFriendly = 1, maxPrice = 50 和 maxDistance = 10 进行过滤后,我们得到了餐馆 3, 餐馆 1 和 餐馆 5(按评分从高到低排序)。 

示例 2:

输入:restaurants = [[1,4,1,40,10],[2,8,0,50,5],[3,8,1,30,4],[4,10,0,10,3],[5,1,1,15,1]], veganFriendly = 0, maxPrice = 50, maxDistance = 10
输出:[4,3,2,1,5]
解释:餐馆与示例 1 相同,但在 veganFriendly = 0 的过滤条件下,应该考虑所有餐馆。

示例 3:

输入:restaurants = [[1,4,1,40,10],[2,8,0,50,5],[3,8,1,30,4],[4,10,0,10,3],[5,1,1,15,1]], veganFriendly = 0, maxPrice = 30, maxDistance = 3
输出:[4,5]

提示:

  • 1 <= restaurants.length <= 10^4
  • restaurants[i].length == 5
  • 1 <= idi, ratingi, pricei, distancei <= 10^5
  • 1 <= maxPrice, maxDistance <= 10^5
  • veganFriendlyi 和 veganFriendly 的值为 0 或 1 。
  • 所有 idi 各不相同。

解法:优先队列(Or 排序)

本题比较简单,只要将符合条件的元素添加进列表再进行排序即可,这里复习一下优先队列的使用方法:

priority_queue:优先队列,本质是堆实现。与队列不同的是,priority_queue只能访问队列头部的信息(使用top),且插入元素后,会自动排序。

基本操作:

  • top(): 访问队头元素
  • empty(): 队列是否为空
  • size():返回队列内元素个数
  • push():插入元素到队尾 (并排序)
  • emplace():原地构造一个元素并插入队列
  • pop():弹出队头元素
  • swap():交换内容

priority_queue<Type, Container, Functional>

  • Type :数据类型,就是优先队列中每一个元素的数据类型
  • Container :容器类型(Container必须是用数组实现的容器,比如vector,deque等等,但不能用 list。STL里面默认用的是vector)【简单理解就是用什么容器实现这个优先级队列】
  • Functional :比较的方式,当需要用自定义的数据类型时才需要传入这三个参数,使用基本数据类型时,只需要传入数据类型,默认是大顶堆【有greater、less和自定义函数,其中greater使得优先队列中的元素升序排列,所以第一个元素(头部)就是最小的元素,也就是小顶堆;less使得元素降序排列,那么第一个元素就是最大的,也就是大顶堆。】

上述部分内容转载自:https://blog.csdn.net/weixin_44225182/article/details/108567330

operator() 函数需要返回一个布尔值,指示两个元素之间的优先级关系。根据返回值的不同,优先队列的排序顺序也会有所不同。

  • 如果 operator() 返回 true,则表示第一个元素具有较高的优先级,它应该排在队列的前面。
  • 如果 operator() 返回 false,则表示第二个元素具有较高的优先级,它应该排在队列的前面。

具体来说,在优先队列中:

  • 如果 operator() 返回 true,则第一个元素在排序时会被认为比第二个元素小或优先级更高,因此会被放在队列的前面。
  • 如果 operator() 返回 false,则第一个元素在排序时会被认为比第二个元素大或优先级较低,因此会被放在队列的后面。

在本题中,我们定义了以下比较算法:

    struct tmp{
        int id;
        int rating;
    };
    struct cmp{
        bool operator()(const tmp &X,const tmp &Y)
        {
            if(X.rating!=Y.rating)
            {
                return X.rating<Y.rating;
            }
            else return X.id<Y.id;
        }
    };

构造优先队列:

priority_queue<tmp,vector<tmp>,cmp >T;

这样就可以将新添加进来的元素自动按规则进行排列。

代码:

class Solution {
public:
    struct tmp{
        int id;
        int rating;
    };
    struct cmp{
        bool operator()(const tmp &X,const tmp &Y)
        {
            if(X.rating!=Y.rating)
            {
                return X.rating<Y.rating;
            }
            else return X.id<Y.id;
        }
    };
    
    vector<int> filterRestaurants(vector<vector<int>>& restaurants, int veganFriendly, int maxPrice, int maxDistance) {
        int len = restaurants.size();
        priority_queue<tmp,vector<tmp>,cmp >T;
        for(int i=0;i<len;i++)
        {
            if(restaurants[i][2]!=veganFriendly&&veganFriendly!=0) continue;
            if(maxPrice<restaurants[i][3]) continue;
            if(maxDistance<restaurants[i][4]) continue;
            tmp rets;
            rets.id = restaurants[i][0];
            rets.rating  = restaurants[i][1];
            T.push(rets);
        }
        vector<int> ans;
        while(!T.empty())
        {
            tmp L = T.top();
            T.pop();
            ans.push_back(L.id);
        }
        return ans;
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值