题目
标题和出处
标题:餐厅过滤器
出处:1333. 餐厅过滤器
难度
3 级
题目描述
要求
给定一个餐馆信息数组 restaurants \texttt{restaurants} restaurants,其中 restaurants[i] = [id i , rating i , veganFriendly i , price i , distance i ] \texttt{restaurants[i] = [id}_\texttt{i}\texttt{, rating}_\texttt{i}\texttt{, veganFriendly}_\texttt{i}\texttt{, price}_\texttt{i}\texttt{, distance}_\texttt{i}\texttt{]} restaurants[i] = [idi, ratingi, veganFriendlyi, pricei, distancei]。需要使用三个过滤器来过滤这些餐馆信息。
素食者友好过滤器 veganFriendly \texttt{veganFriendly} veganFriendly 的值可以为 true \texttt{true} true 或者 false \texttt{false} false,如果为 true \texttt{true} true 就意味着应该只包括 veganFriendly i \texttt{veganFriendly}_\texttt{i} veganFriendlyi 为 true \texttt{true} true 的餐馆,为 false \texttt{false} false 则意味着可以包括任何餐馆。此外,还有最大价格 maxPrice \texttt{maxPrice} maxPrice 和最大距离 maxDistance \texttt{maxDistance} maxDistance 两个过滤器,分别表示考虑餐厅的价格因素和距离因素的最大值。
过滤后返回餐馆的 id \texttt{id} id,按照 rating \texttt{rating} rating 从高到低排序。如果 rating \texttt{rating} rating 相同,那么按 id \texttt{id} id 从高到低排序。简单起见, veganFriendly i \texttt{veganFriendly}_\texttt{i} veganFriendlyi 和 veganFriendly \texttt{veganFriendly} veganFriendly 为 true \texttt{true} true 时取值为 1 \texttt{1} 1,为 false \texttt{false} false 时取值为 0 \texttt{0} 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
\texttt{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}
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]
\texttt{[3,1,5]}
[3,1,5]
解释:
这些餐馆为:
餐馆
1
\texttt{1}
1
[id=1,
rating=4,
veganFriendly=1,
price=40,
distance=10]
\texttt{[id=1, rating=4, veganFriendly=1, price=40, distance=10]}
[id=1, rating=4, veganFriendly=1, price=40, distance=10]
餐馆
2
\texttt{2}
2
[id=2,
rating=8,
veganFriendly=0,
price=50,
distance=5]
\texttt{[id=2, rating=8, veganFriendly=0, price=50, distance=5]}
[id=2, rating=8, veganFriendly=0, price=50, distance=5]
餐馆
3
\texttt{3}
3
[id=3,
rating=8,
veganFriendly=1,
price=30,
distance=4]
\texttt{[id=3, rating=8, veganFriendly=1, price=30, distance=4]}
[id=3, rating=8, veganFriendly=1, price=30, distance=4]
餐馆
4
\texttt{4}
4
[id=4,
rating=10,
veganFriendly=0,
price=10,
distance=3]
\texttt{[id=4, rating=10, veganFriendly=0, price=10, distance=3]}
[id=4, rating=10, veganFriendly=0, price=10, distance=3]
餐馆
5
\texttt{5}
5
[id=5,
rating=1,
veganFriendly=1,
price=15,
distance=1]
\texttt{[id=5, rating=1, veganFriendly=1, price=15, distance=1]}
[id=5, rating=1, veganFriendly=1, price=15, distance=1]
在按照
veganFriendly
=
1,
maxPrice
=
50
和
maxDistance
=
10
\texttt{veganFriendly = 1, maxPrice = 50 和 maxDistance = 10}
veganFriendly = 1, maxPrice = 50 和 maxDistance = 10 进行过滤后,我们得到了餐馆
3
\texttt{3}
3、餐馆
1
\texttt{1}
1 和餐馆
5
\texttt{5}
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
\texttt{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}
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]
\texttt{[4,3,2,1,5]}
[4,3,2,1,5]
解释:餐馆与示例 1 相同,但在
veganFriendly
=
0
\texttt{veganFriendly = 0}
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
\texttt{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}
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]
\texttt{[4,5]}
[4,5]
数据范围
- 1 ≤ restaurants.length ≤ 10 4 \texttt{1} \le \texttt{restaurants.length} \le \texttt{10}^\texttt{4} 1≤restaurants.length≤104
- restaurants[i].length = 5 \texttt{restaurants[i].length} = \texttt{5} restaurants[i].length=5
- 1 ≤ id i , rating i , price i , distance i ≤ 10 5 \texttt{1} \le \texttt{id}_\texttt{i}\texttt{, rating}_\texttt{i}\texttt{, price}_\texttt{i}\texttt{, distance}_\texttt{i} \le \texttt{10}^\texttt{5} 1≤idi, ratingi, pricei, distancei≤105
- 1 ≤ maxPrice, maxDistance ≤ 10 5 \texttt{1} \le \texttt{maxPrice, maxDistance} \le \texttt{10}^\texttt{5} 1≤maxPrice, maxDistance≤105
- veganFriendly i \texttt{veganFriendly}_\texttt{i} veganFriendlyi 和 veganFriendly \texttt{veganFriendly} veganFriendly 的值为 0 \texttt{0} 0 或 1 \texttt{1} 1
- 所有 id i \texttt{id}_\texttt{i} idi 各不相同
解法
思路和算法
每个餐馆有五项信息:编号、评分、素食者友好、价格和距离,其中编号和评分用于排序,素食者友好、价格和距离用于过滤。由于只有符合三个过滤器条件的餐馆会包含在结果中,因此首先使用三个过滤器对餐馆过滤,排除不符合三个过滤器条件的餐馆,然后对符合三个过滤器条件的餐馆基于评分和编号降序排序。
对每个餐馆使用三个过滤器过滤的规则如下。
-
素食者友好过滤器:如果餐馆是素食者友好的,则无论给定的素食者友好条件 veganFriendly \textit{veganFriendly} veganFriendly 是 1 1 1 还是 0 0 0,餐馆都符合条件;如果餐馆不是素食者友好的,则只有当给定的素食者友好条件 veganFriendly \textit{veganFriendly} veganFriendly 是 0 0 0 的情况下,餐馆才符合条件。因此餐馆符合素食者友好过滤器条件等价于餐馆是素食者友好的或者给定的素食者友好条件 veganFriendly \textit{veganFriendly} veganFriendly 是 0 0 0。
-
最大价格过滤器:如果餐馆价格不超过给定的最大价格 maxPrice \textit{maxPrice} maxPrice,则符合条件。
-
最大距离过滤器:如果餐馆距离不超过给定的最大距离 maxDistance \textit{maxDistance} maxDistance,则符合条件。
创建排序列表存储符合三个过滤器条件的餐馆,排序列表用于对餐馆排序。由于排序的依据只有评分和编号,因此排序列表中只需要存储餐馆的编号和评分。将所有符合三个过滤器条件的餐馆加入排序列表之后,对列表排序,需要自定义如下排序规则。
-
如果两个餐馆的评分不同,则根据评分降序排序。
-
如果两个餐馆的评分相同,则根据编号降序排序。
排序之后,创建结果列表,依次将排序列表中的每个餐馆的编号添加到结果列表中,最后返回结果列表。
代码
class Solution {
public List<Integer> filterRestaurants(int[][] restaurants, int veganFriendly, int maxPrice, int maxDistance) {
List<int[]> restaurantList = new ArrayList<int[]>();
for (int[] restaurant : restaurants) {
if ((restaurant[2] == 1 || veganFriendly == 0) && restaurant[3] <= maxPrice && restaurant[4] <= maxDistance) {
restaurantList.add(new int[]{restaurant[0], restaurant[1]});
}
}
Collections.sort(restaurantList, (a, b) -> {
if (a[1] != b[1]) {
return b[1] - a[1];
} else {
return b[0] - a[0];
}
});
List<Integer> filter = new ArrayList<Integer>();
int size = restaurantList.size();
for (int i = 0; i < size; i++) {
int[] restaurant = restaurantList.get(i);
filter.add(restaurant[0]);
}
return filter;
}
}
复杂度分析
-
时间复杂度: O ( n log n ) O(n \log n) O(nlogn),其中 n n n 是数组 restaurants \textit{restaurants} restaurants 的长度。过滤餐馆并将符合三个过滤器条件的餐馆添加到排序列表需要 O ( n ) O(n) O(n) 的时间,对列表排序需要 O ( n log n ) O(n \log n) O(nlogn) 的时间,排序后将餐馆编号填入结果列表需要 O ( n ) O(n) O(n) 的时间,时间复杂度是 O ( n log n ) O(n \log n) O(nlogn)。
-
空间复杂度: O ( n ) O(n) O(n),其中 n n n 是数组 restaurants \textit{restaurants} restaurants 的长度。排序列表需要 O ( n ) O(n) O(n) 的空间。