[1333. 餐厅过滤器] | 刷题打卡

431 阅读3分钟

前言

掘金最近在开刷题活动,也就过来凑热闹了。这道题是随机刷出来的

题目描述

因为复制文字的话格式不好看,我直接贴图,也可以直接看原文

难度:中等

示例

示例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]

提示:

解题思路

这就是一道比较业务型的题目了,首先是筛选出符合条件的餐馆:

  • 当前用餐者是否素食者,是的话餐馆只能是素食馆
  • 距离不能超过可接受距离
  • 价格不能超过可接受价格 这一步一般O(n)的复杂度就能解决了
        for (int[] restaurant : restaurants) {
            if ((veganFriendly == 1 && restaurant[2] != 1) || restaurant[3] > maxPrice || restaurant[4] > maxDistance) {
                continue;
            }
        }

其次是筛选出来的餐馆需要排序,这里不建议在筛选时候进行排序,否则会造成很多重复运算。
这里我选择了用快排来进行最终排序,时间复杂度为O (nlogn)。

AC代码

public class Solution {
    /**
     * restaurants[i] = [idi, ratingi, veganFriendlyi, pricei, distancei]
     *
     * @param restaurants
     * @param veganFriendly
     * @param maxPrice
     * @param maxDistance
     * @return
     */
    public List<Integer> filterRestaurants(int[][] restaurants,
                                           int veganFriendly, int maxPrice,
                                           int maxDistance) {

        List<int[]> temp = new ArrayList<>();
        for (int[] restaurant : restaurants) {
            if ((veganFriendly == 1 && restaurant[2] != 1) || restaurant[3] > maxPrice || restaurant[4] > maxDistance) {
                continue;
            }
            temp.add(restaurant);
        }
        quickSort(temp, 0, temp.size() - 1);
        List<Integer> result = new ArrayList<>();
        for (int[] r : temp) {
            result.add(r[0]);
        }
        return result;

    }


    /**
     * @param o1
     * @param o2
     * @return
     */
    private static int compare(int[] o1, int[] o2) {
        if (o1[1] > o2[1]) {
            return 1;
        } else if (o1[1] == o2[1]) {
            return Integer.compare(o1[0], o2[0]);
        } else {
            return -1;
        }
    }

    private static void quickSort(List<int[]> arr, int low, int high) {
        int i, j;
        int[] temp, t;
        if (low > high) {
            return;
        }
        i = low;
        j = high;
        //temp就是基准位
        temp = arr.get(low);

        while (i < j) {
            //先看右边,依次往左递减
            while (compare(temp, arr.get(j)) >= 0 && i < j) {
                j--;
            }
            //再看左边,依次往右递增
            while (compare(temp, arr.get(i)) <= 0 && i < j) {
                i++;
            }
            //如果满足条件则交换
            if (i < j) {
                t = arr.get(j);
                arr.set(j, arr.get(i));
                arr.set(i, t);
            }

        }
        //最后将基准为与i和j相等位置的数字交换
        arr.set(low, arr.get(i));
        arr.set(i, temp);
        //递归调用左半数组
        quickSort(arr, low, j - 1);
        //递归调用右半数组
        quickSort(arr, j + 1, high);
    }

    public static void main(String[] args) {
        Solution s = new Solution();
        int[][] res = {{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}};
        print(s.filterRestaurants(res, 1, 50, 10));

        res = new int[][]{{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}};
        print(s.filterRestaurants(res, 0, 50, 10));
    }

    private static void print(List<Integer> list){
        for (Integer integer : list) {
            System.out.print(integer + " ");
        }
        System.out.println();
    }

}

总结

可以看到最终时间复杂度为O (nlogn),4ms就跑完了全部用例,但是内存消耗却不乐观,因为我们牺牲了一部分内存来缓存第一步得到的结果。
实际开发中可根据实际情况进行时间与空间的取舍

本文正在参与「掘金 2021 春招闯关活动」, 点击查看 活动详情