Leetcode1333.餐厅过滤器——使用stream流

2023-11-09

引入

在上周周赛中,有这么一道题

1333.餐厅过滤器
给你一个餐馆信息数组 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 。
在这里插入图片描述

本题题目条件的确是特别的多,我们先来捋一捋:
首先查看题目给定的函数,其输入为:

public List<Integer> filterRestaurants(int[][] restaurants, int veganFriendly, int maxPrice, int maxDistance)
  1. restaurants的二维数组,每个餐厅包含了id、rating、veganFriendly、price、distance这五个元素,也就是每个restaurant[i]包含了长度为5的数组。
  2. 然后会根据三个值来过滤,分别是veganFriendly,这是个二元变量,由0或者1来表示;maxPrice也就是说price要小于这个值;maxDistance也就是会所distance要小于这个值。所以这三个输入给定了筛选的条件。
  3. 筛选出来的值排序,根据什么来排序呢?rating和id来排序,先比较rating然后比较id。
  4. 输出id。

总结到上面这一步,我们发现,本题实际上是十分简单的,就是进行filter->sort,所以,我们这里使用java8的特性流来解题,显得更加优雅

本题题解

本题思路基本如下:

+--------------------+       +------+   +------+   +---+   +-------+
| stream of elements +-----> |filter+-> |sorted+-> |map+-> |collect|
+--------------------+       +------+   +------+   +---+   +-------+

  1. 生成流

首先将输入转化为流的形式

+--------------------+      
| stream of elements |
+--------------------+       

一般是通过这样的方式转换为流:

List<Object> list=new ArrayList<>();
list.stream();

所以,我们需要创建一个对象来保存餐厅:

    private class Restaurant {
        int id;
        int rating;
        int veganFriendly;
        int price;
        int distance;

        public Restaurant(int id, int rating, int veganFriendly, int price, int distance) {
            this.id = id;
            this.rating = rating;
            this.veganFriendly = veganFriendly;
            this.price = price;
            this.distance = distance;
        }
    }

然后创建这个List:

        List<Restaurant> restaurantList = new ArrayList<>();
        for (int[] restaurant : restaurants) {
            restaurantList.add(new Restaurant(restaurant[0], restaurant[1],
                    restaurant[2], restaurant[3], restaurant[4]));
        }

于是这个stream就出来了:

restaurantList.stream();

  1. 过滤filter
+------+  
|filter|
+------+   

过滤其实就是根据过滤条件来过滤了,一般是通过下面的方法:

list.stream().filter(o->o.value>5);//过滤一个出布尔值

本题的过滤条件已经讲的很清楚了,会根据三个值来过滤,分别是veganFriendly,这是个二元变量,由0或者1来表示;maxPrice也就是说price要小于这个值;maxDistance也就是会所distance要小于这个值。

所以其代码为:

restaurantList.stream().filter(r->r.veganFriendly >= veganFriendly
								&&r.price<=maxPrice
								&&r.distance<maxDistance);

  1. 排序
+------+  
|sorted|
+------+   

一般排序的代码如下:

//以下代码片段使用 sorted 方法对输出的 10 个随机数进行排序
Random random = new Random();
random.ints().limit(10).sorted();

上面的代码是对随机数(int类型)从小到大排序,我们这里传入的是一个对象Restaurant,所以不能简单的使用sorted()方法。
如果只是简单的按照rating排序,可以这么写:

restaurantList.stream().sorted(Comparator.comparing(Restaurant::getRating));

或者:

restaurantList.stream().sorted((o1,o2)->{
	return o2.rating-o1.rating;
});

不过本题的要求更多一点:
过滤后返回餐馆的 id,按照 rating 从高到低排序。如果 rating 相同,那么按 id 从高到低排序。
所以我们按照第二种方式来写:

restaurantList.stream().sorted((o1, o2) -> {
            if (o1.rating == o2.rating) {
                return o2.id - o1.id;
            }
            return o2.rating - o1.rating;
        })

  1. 返回id
+---+  
|map|
+---+   

由于我们只需要返回id,所以需要采用map,一般map是这样用的:

// map 输出了元素对应的平方数
List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
// 获取对应的平方数
List<Integer> squaresList = numbers.stream().map( i -> i*i);

所以在这里,我只需要:

restaurantList.stream().map(r->r.id);

  1. 返回List
+-------+  
|collect|
+-------+   

本题要求返回的是List<Integer>,所以我们只需要这样处理:

restaurantList.stream().map(r->r.id).collect(Collectors.toList());

完整代码:

class Solution {
    public List<Integer> filterRestaurants(int[][] restaurants, int veganFriendly, int maxPrice, int maxDistance) {
        List<Restaurant> restaurantList = new ArrayList<>();
        for (int[] restaurant : restaurants) {
            restaurantList.add(new Restaurant(restaurant[0], restaurant[1],
                    restaurant[2], restaurant[3], restaurant[4]));
        }
        return restaurantList.stream().filter(r -> r.veganFriendly >= veganFriendly
                && r.price <= maxPrice && r.distance <= maxDistance).sorted((o1, o2) -> {
            if (o1.rating == o2.rating) {
                return o2.id - o1.id;
            }
            return o2.rating - o1.rating;
        }).map(r -> r.id).collect(Collectors.toList());
    }
    
    private class Restaurant {
        int id;
        int rating;
        int veganFriendly;
        int price;
        int distance;

        public Restaurant(int id, int rating, int veganFriendly, int price, int distance) {
            this.id = id;
            this.rating = rating;
            this.veganFriendly = veganFriendly;
            this.price = price;
            this.distance = distance;
        }
    }
}

后记:int[]、Integer[]、List的互相转化

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
 
public class Main {
    public static void main(String[] args) {
        int[] data = {4, 5, 3, 6, 2, 5, 1};
 
        // int[] 转 List<Integer>
        List<Integer> list1 = Arrays.stream(data).boxed().collect(Collectors.toList());
        // Arrays.stream(arr) 可以替换成IntStream.of(arr)。
        // 1.使用Arrays.stream将int[]转换成IntStream。
        // 2.使用IntStream中的boxed()装箱。将IntStream转换成Stream<Integer>。
        // 3.使用Stream的collect(),将Stream<T>转换成List<T>,因此正是List<Integer>。
 
        // int[] 转 Integer[]
        Integer[] integers1 = Arrays.stream(data).boxed().toArray(Integer[]::new);
        // 前两步同上,此时是Stream<Integer>。
        // 然后使用Stream的toArray,传入IntFunction<A[]> generator。
        // 这样就可以返回Integer数组。
        // 不然默认是Object[]。
 
        // List<Integer> 转 Integer[]
        Integer[] integers2 = list1.toArray(new Integer[0]);
        //  调用toArray。传入参数T[] a。这种用法是目前推荐的。
        // List<String>转String[]也同理。
 
        // List<Integer> 转 int[]
        int[] arr1 = list1.stream().mapToInt(Integer::valueOf).toArray();
        // 想要转换成int[]类型,就得先转成IntStream。
        // 这里就通过mapToInt()把Stream<Integer>调用Integer::valueOf来转成IntStream
        // 而IntStream中默认toArray()转成int[]。
 
        // Integer[] 转 int[]
        int[] arr2 = Arrays.stream(integers1).mapToInt(Integer::valueOf).toArray();
        // 思路同上。先将Integer[]转成Stream<Integer>,再转成IntStream。
 
        // Integer[] 转 List<Integer>
        List<Integer> list2 = Arrays.asList(integers1);
        // 最简单的方式。String[]转List<String>也同理。

        // 同理
        String[] strings1 = {"a", "b", "c"};
        // String[] 转 List<String>
        List<String> list3 = Arrays.asList(strings1);
        // List<String> 转 String[]
        String[] strings2 = list3.toArray(new String[0]);
 
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Leetcode1333.餐厅过滤器——使用stream流 的相关文章

  • openblas第一弹:openblas 使用说明和常用接口介绍

    openblas 使用说明 openblas 是一个开源的矩阵计算库 包含了诸多的精度和形式的矩阵计算算法 就精度而言 包括float和double 两种数据类型的数据 其矩阵调用函数也是不一样 不同矩阵 其计算方式也是有所不同 姑且认为向
  • C++设计模式 - 组合模式(Composite)

    数据结构模式 常常有一 些组件在内部具有特定的数据结构 如果让客户程序依赖这些特定的数据结构 将极大地破坏组件的复用 这时候 将这些特定数据结构封装在内部 在外部提供统一的接口 来实现与特定数据结构无关的访问 是一种行之有效的解决方案 典型
  • 遗传算法基本介绍

    1 主要解决什么问题 是一种仿生全局优化算法 2 原理 思路是什么 选择 优胜劣汰 交叉 变异 一些重要概念 生物遗传概念在遗传算法中的对应关系 编码策略 常用的遗传算法编码方法主要有 二进制编码 浮点数编码等 可以证明 二进制编码比浮点数
  • 在html中加入网址,网页超链接怎么做,添加超链接网址的的详细步骤

    此系列教程主要讲解HTML从基础到精通 自己能够设计一个完整的前端网页项目 程序员写代码 在HTML中添加图片其实很简单 就是添加一个img的标签 图片标签的语法 一般有src alt width height四种属性就够用了 效果 图片的

随机推荐

  • 智能音箱借ChatGPT重获“新生”?

    曾经靠语音助手红极一时的智能音箱 近年来的市场表现却欠佳 据洛图科技发布的最新 中国智能音箱零售市场月度追踪 报告显示 2022年中国智能音箱总销量为2631万台 同比下降28 市场销售额为75 3亿元 同比下降25 而IDC发布的2023
  • 华为OD机试 - 太阳能板最大面积(Java)

    题目描述 给航天器一侧加装长方形或正方形的太阳能板 图中的红色斜线区域 需要先安装两个支柱 图中的黑色竖条 再在支柱的中间部分固定太阳能板 但航天器不同位置的支柱长度不同 太阳能板的安装面积受限于最短一侧的那根支柱长度 如图 现提供一组整形
  • 计算机中的打印机,如何添加打印机,教您电脑如何添加打印机

    打印机是我们工作中不可缺少的办公设备 那如果电脑上没安装打印机 可以进行打印吗 我们可以通过连接到同一网络上的打印机进行打印作业 那电脑怎样进行添加打印机呢 下面 小编给大家带来了电脑添加打印机的图文 打印机是现在我们办公设备的必要用品之一
  • 如何定位Release 版本中程序崩溃的位置 ---利用map文件 拦截windows崩溃函数

    1 案例描述 作为Windows程序员 平时最担心见到的事情可能就是程序发生了崩溃 异常 这时Windows会提示该程序执行了非法操作 即将关闭 请与您的供应商联系 呵呵 这句微软的 名言 恐怕是程序员最怕见也最常见的东西了 在一个大型软件
  • spring boot集成mybatis无法扫描mapper文件(坑)

    大半天耗在这上面 真的无语了 现象解决了 原因待查找 首先 如果你的spring boot集成mybatis项目报这个错 同时你使用的是YML的配置方式 再同时你用的是Intellij 那么就往下看吧 解决方法就是 使用这种配置方式 命名为
  • 马虎的算式

    标题 马虎的算式 小明是个急性子 上小学的时候经常把老师写在黑板上的题目抄错了 有一次 老师出的题目是 36 x 495 他却给抄成了 396 x 45 但结果却很戏剧性 他的答案竟然是对的 因为 36 495 396 45 17820 类
  • 刷题之反转字符串

    编写一个函数 其作用是将输入的字符串反转过来 输入字符串以字符数组 s 的形式给出 不要给另外的数组分配额外的空间 你必须原地修改输入数组 使用 O 1 的额外空间解决这一问题 示例 1 输入 s h e l l o 输出 o l l e
  • LAST_INSERT_ID使用造成订单串单问题

    订单串单问题 代码 String sql insert into this update sql List
  • 用动态数组实现了顺序表

    用动态数组实现了顺序表 作者 吕翔宇 e mail 630056108 qq com ALL RIGHTS RESERVED 版权所有 include
  • Spring Boot定时任务在分布式环境下的轻量级解决方案

    文章非原创 转载简书 原作者 foundwei 转载链接 https www jianshu com p 41970ba48453 Spring Boot提供了一个叫做Spring Task的任务调度工具 支持注解和配置文件形式 支持Cro
  • CGAL计算几何算法库安装和使用(一)

    CGAL是使用C 开发的计算几何算法库 提供Delaunay三角网 网格生成 多边形 以及各种几何处理算法 应用领域 计算机图形学 科学可视化 计算机辅助设计与建模 地理信息系统 分子生物学 医学影像学 机器人学和运动规划 和数值方法 1
  • KVM同步脏页原理

    文章目录 硬件基础 SPTE 硬件要素 工作流程 PML 硬件要素 工作流程 数据结构 用户态 内核态 API 脏页开启 脏页获取 流程 使能记录 记录脏页 流程图 具体过程 获取脏页 流程图 具体过程 实验 QEMU在内存迁移阶段首先会标
  • Struts2框架验证

    struts2有框架验证 我这边主要说的是XML配置的struts2的框架验证 继承validate方法的验证还是比较容易的 至于有人用注解来验证不怎么常见我也不讲了 感觉好多东西总结的都会有注解来掺和一脚 比如spring注入方式 最常见
  • Python全系列教程:超详细1小时学会Python,太简单了

    1 Hello world 安装完Python之后 打开IDLE Python GUI 该程序是Python语言解释器 你写的语句能够立即运行 我们写下一句著名的程序语句 并按回车 你就能看到这句被K R引入到程序世界的名言 在解释器中选择
  • UFT 自带两个经典sample航空订票应用程序

    大家知道UFT是QTP的升级换代产品 一定保留上一版系统原有的一些的痕迹 比如经典的Flights应用 安装路径 D Program Files x86 Micro Focus Unified Functional Testing samp
  • 单片机定时器/计数器、中断和串口控制位

    一 定时器 计数器 1 定时器控制寄存器 TCON TCON TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0 TF1 TF0 定时器 计数器中断请求标志位当定时器计数满溢出回零时 有硬件置位 并可申请中断 当CPU响应中断并
  • C语言:(含大量图解)你真的了解结构体吗?

    文章目录 结构体 结构体的定义 结构体大小计算 结构体的对齐规则 关于对齐规则的解释 为什么C语言要这样进行大小设定 平台移植原因 追求高性能 修改默认对齐数 结构体传参问题 结构体 结构体的定义 结构体是一些值的集合 这些值被称为成员变量
  • 【RPC】RPC的序列化方式

    序列化 网络传输的数据必须是二进制数据 但调用方请求的出入参数都是对象 对象是不能直接在网络中传输的 所以我们需要提前把它转成可传输的二进制 并且要求转换算法是可逆的 这个过程我们一般叫做 序列化 这时 服务提供方就可以正确地从二进制数据中
  • 小程序——wxml组件和wxss适配

    一 和以往代码区别 wxml html zhuiy css view div text文字 加入这个可以长按选中 否则不能复制 image img button button form form input input label labe
  • Leetcode1333.餐厅过滤器——使用stream流

    文章目录 引入 本题题解 后记 int Integer List的互相转化 引入 在上周周赛中 有这么一道题 1333 餐厅过滤器 给你一个餐馆信息数组 restaurants 其中 restaurants i idi ratingi ve