前言
掘金最近在开刷题活动,也就过来凑热闹了。这道题是随机刷出来的
题目描述
因为复制文字的话格式不好看,我直接贴图,也可以直接看原文
难度:中等
示例
示例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 春招闯关活动」, 点击查看 活动详情