题目描述:
给你一个餐馆信息数组 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;
}
};