排序题目:餐厅过滤器

题目

标题和出处

标题:餐厅过滤器

出处: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} 1restaurants.length104
  • 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} 1idi, ratingi, pricei, distancei105
  • 1 ≤ maxPrice,   maxDistance ≤ 10 5 \texttt{1} \le \texttt{maxPrice, maxDistance} \le \texttt{10}^\texttt{5} 1maxPrice, maxDistance105
  • 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) 的空间。

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

伟大的车尔尼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值