代码随想录day29 | leetcode 134.加油站 135.分发糖果 860.柠檬水找零 406.根据身高重建队列

134.加油站

思路

如果总油量减去总消耗大于等于零那么一定可以跑完一圈,说明 各个站点的加油站 剩油量rest[i]相加一定是大于等于零的。
每个加油站的剩余量rest[i]为gas[i] - cost[i]。
i从0开始累加rest[i],和记为curSum,一旦curSum小于零,说明[0, i]区间都不能作为起始位置,因为这个区间选择任何一个位置作为起点,到i这里都会断油,那么起始位置从i+1算起,再从0计算curSum。

Java

class Solution {
    public int jump(int[] nums) {
        int jumps = 0; // 跳跃次数
        int curEnd = 0; // 当前跳跃覆盖的最远位置
        int nextMax = 0; // 下一次跳跃覆盖的最远位置

        for (int i = 0; i < nums.length - 1; i++) {
            nextMax = Math.max(nextMax, i + nums[i]); // 更新下一次的最远位置

            if (i == curEnd) { // 当前跳跃到达了覆盖范围的末尾
                jumps++; // 增加跳跃次数
                curEnd = nextMax; // 更新当前覆盖范围
                if (curEnd >= nums.length - 1) { // 如果已经可以到达终点,提前结束
                    break;
                }
            }
        }
        return jumps;
    }
}

关键逻辑

  1. curSum 重置
    • curSum < 0 时,说明从当前起点到当前站点之间的油量不足以到达下一站。
    • 此时假设下一站为新的起点,并将 curSum 重置为 0。
    • 因为问题保证至少有一个解,所以继续累加判断新的起点即可。
  2. totalSum 判断
    • 如果整个环路的总净油量(totalSum)小于 0,则无论从哪里开始,油量都不足以完成一圈。

135.分发糖果

思路

这道题目一定是要确定一边之后,再确定另一边,例如比较每一个孩子的左边,然后再比较右边,如果两边一起考虑一定会顾此失彼。
先确定右边评分大于左边的情况(也就是从前向后遍历)
再确定左孩子大于右孩子的情况(从后向前遍历)

Java

class Solution {
    public int candy(int[] ratings) {
        int len = ratings.length;
        int[] candyVec = new int[len];
        int result = 0;

        // 初始化,每个人至少有一个糖果
        for (int i = 0; i < len; i++) {
            candyVec[i] = 1;
        }

        // 从左往右遍历
        for (int i = 1; i < len; i++) {
            if (ratings[i] > ratings[i - 1]) {
                candyVec[i] = candyVec[i - 1] + 1;
            }
        }

        // 从右往左遍历,同时计算结果
        for (int i = len - 2; i >= 0; i--) {
            if (ratings[i] > ratings[i + 1]) {
                candyVec[i] = Math.max(candyVec[i], candyVec[i + 1] + 1);
            }
        }

        // 累加所有糖果
        for (int candy : candyVec) {
            result += candy;
        }

        return result;
    }
}

关键逻辑解析

  1. 左遍历规则
    • 如果当前学生的评分比左边的高,则糖果数应该比左边多 1。
    • 遍历后,保证每个学生的糖果满足“比左边评分高”的条件。
  2. 右遍历规则
    • 如果当前学生的评分比右边高,则糖果数应该比右边多 1。
    • 同时取当前糖果数和(右侧糖果数 + 1)的较大值,确保满足两侧评分的规则。

860.柠檬水找零

思路

只需要维护三种金额的数量,5,10和20。
有如下三种情况:
情况一:账单是5,直接收下。
情况二:账单是10,消耗一个5,增加一个10
情况三:账单是20,优先消耗一个10和一个5,如果不够,再消耗三个5

Java

class Solution {
    public boolean lemonadeChange(int[] bills) {
        int five = 0;
        int ten = 0;

        for (int i = 0; i < bills.length; i++) {
            if (bills[i] == 5) {
                five++;
            } else if (bills[i] == 10) {
                five--;
                ten++;
            } else if (bills[i] == 20) {
                if (ten > 0) {
                    ten--;
                    five--;
                } else {
                    five -= 3;
                }
            }
            if (five < 0 || ten < 0) return false;
        }
        
        return true;
    }
}

总结

咋眼一看好像很复杂,分析清楚之后,会发现逻辑其实非常固定。
这道题目可以告诉大家,遇到感觉没有思路的题目,可以静下心来把能遇到的情况分析一下,只要分析到具体情况了,一下子就豁然开朗了。
如果一直陷入想从整体上寻找找零方案,就会把自己陷进去,各种情况一交叉,只会越想越复杂了。

406.根据身高重建队列

思路

与135. 分发糖果类似,遇到两个维度权衡的时候,一定要先确定一个维度,再确定另一个维度。
按照身高排序之后,优先按身高高的people的k来插入,后序插入节点也不会影响前面已经插入的节点,最终按照k的规则完成了队列。
局部最优:优先按身高高的people的k来插入。插入操作过后的people满足队列属性

Java

class Solution {
    public int[][] reconstructQueue(int[][] people) {
        // 身高从大到小排(身高相同k小的站前面)
        Arrays.sort(people, (a, b) -> {
            if (a[0] == b[0]) return a[1] - b[1];   //如果身高相同,按 k 值升序排列
            return b[0] - a[0];   //如果身高不同,按身高降序排列
        });
        LinkedList<int[]> que = new LinkedList<>();
        for (int[] p : people) {
            que.add(p[1],p);   //将当前元素插入到索引为 p[1] 的位置
        }
        return que.toArray(new int[people.length][]);
    }
}

Lambda 表达式的作用

Lambda 表达式的格式是:

(parameters) -> expression 或 { statements }

它的作用是简化匿名类的写法,用来快速定义函数式接口的实现。对于 Comparator 接口,Lambda 表达式替代了传统的匿名类来定义排序规则。

Lambda 表达式在 Arrays.sort 中的使用

Arrays.sort(people, (a, b) -> { ... }) 是对二维数组 people 进行排序。

  • abpeople 数组中的两个元素(在这里每个元素是一个长度为 2 的数组)。
  • Comparator 接口通过 compare(T o1, T o2) 定义排序规则,这里的 ab 就是 o1o2

代码中的逻辑

Arrays.sort(people, (a, b) -> {
    if (a[0] == b[0]) return a[1] - b[1];   // 身高相同时,按 k 值升序排列
    return b[0] - a[0];   // 身高不同,按身高降序排列
});
1. 如果身高相同 (a[0] == b[0]):
return a[1] - b[1];
  • 比较 a[1]b[1] 的大小。
  • a[1] - b[1] > 0 时,b 会排在 a 前面(升序排列)。
  • 简单理解就是 k 值越小的排在前面
2. 如果身高不同 (a[0] != b[0]):
return b[0] - a[0];
  • 比较 b[0]a[0] 的大小。
  • b[0] - a[0] > 0 时,a 会排在 b 前面(降序排列)。
  • 简单理解就是 身高越高的排在前面

Lambda 表达式的展开形式

用传统匿名类实现同样功能:

Arrays.sort(people, new Comparator<int[]>() {
    @Override
    public int compare(int[] a, int[] b) {
        if (a[0] == b[0]) {
            return a[1] - b[1];
        }
        return b[0] - a[0];
    }
});

可以看到,Lambda 表达式 (a, b) -> {...} 简化了匿名类的写法。


总结

  1. Lambda 表达式语法
    • (a, b) -> 表达式
    • (a, b) -> { 代码块 }
  2. 本例中:
    • ab 是二维数组 people 中的两个元素。
    • a[0]b[0] 是身高,a[1]b[1] 是 k 值。
    • 排序规则:- 先按身高降序排列。
      • 若身高相同,按 k 值升序排列。

比较器的返回值在排序中的含义

在 Java 中,Comparatorcompare 方法返回一个整数,用于定义排序规则:

  • 负值:第一个参数应该排在第二个参数前面。
  • :两个参数在排序中视为相等。
  • 正值:第一个参数应该排在第二个参数后面。

a[1] - b[1] 的作用

假设 ab 是两个数组(例如,a = [h1, k1]b = [h2, k2]),a[1]b[1] 分别表示它们的 k 值。

  1. a[1] < b[1]
    • 计算结果为负值,意味着 a 应该排在 b 的前面。
  2. a[1] > b[1]
    • 计算结果为正值,意味着 b 应该排在 a 的前面。
  3. a[1] == b[1]
    • 计算结果为零,表示 ab 在这个维度上视为相等,排序保持当前顺序(稳定排序)。

因此,return a[1] - b[1] 会让 k 值按升序排列,因为 k 值小的会排在前面。

所以b[0] - a[0]也是同理

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/948848.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

NVIDIA DLI课程《NVIDIA NIM入门》——学习笔记

先看老师给的资料&#xff1a; NVIDIA NIM是 NVIDIA AI Enterprise 的一部分&#xff0c;是一套易于使用的预构建容器工具&#xff0c;目的是帮助企业客户在云、数据中心和工作站上安全、可靠地部署高性能的 AI 模型推理。这些预构建的容器支持从开源社区模型到 NVIDIA AI 基础…

物联网云平台:构建物联网生态的核心

我们常说的物联网&#xff0c;简称是IoT&#xff0c; 全称 Internet of Things。 用通俗的语言理解物联网&#xff0c;其实就是万事万物的互联网络。物联网概念也已经传播很多年了&#xff0c; 目前正在各行各业发挥力量。 要构建一个物联网生态&#xff0c; 我们首先想到的是智…

VS2022引入sqlite数据库交互

法一&#xff1a;用官网编译好的动态库(推荐) 下载所需文件 sqlite官网地址&#xff1a;https://www.sqlite.org/howtocompile.html 下载以下的2个压缩包 第一个压缩包 sqlite-amalgamation-xxxx.zip&#xff0c;xxxx是版本号,保持一致即可&#xff0c;这里面有sqite3.h 第…

设计模式学习[15]---适配器模式

文章目录 前言1.引例2.适配器模式2.1 对象适配器2.2 类适配器 总结 前言 这个模式其实在日常生活中有点常见&#xff0c;比如我们的手机取消了 3.5 m m 3.5mm 3.5mm的接口&#xff0c;只留下了一个 T y p e − C Type-C Type−C的接口&#xff0c;但是我现在有一个 3.5 m m 3.…

Markdown如何导出Html文件Markdown文件

Markdown如何导出Html文件Markdown文件 前言语法详解小结其他文章快来试试吧☺️ Markdown 导出 HTML &#x1f448;点击这里也可查看 前言 Markdown的源文件以md为后缀。Markdown是HTML语法的简化版本&#xff0c;它本身不带有任何样式信息。我们所看到的Markdown网页(如&…

Python安装(新手详细版)

前言 第一次接触Python&#xff0c;可能是爬虫或者是信息AI开发的小朋友&#xff0c;都说Python 语言简单&#xff0c;那么多学一些总是有好处的&#xff0c;下面从一个完全不懂的Python 的小白来安装Python 等一系列工作的记录&#xff0c;并且遇到的问题也会写出&#xff0c…

JMeter + Grafana +InfluxDB性能监控 (二)

您可以通过JMeter、Grafana 和 InfluxDB来搭建一个炫酷的基于JMeter测试数据的性能测试监控平台。 下面&#xff0c;笔者详细介绍具体的搭建过程。 安装并配置InfluxDB 您可以从清华大学开源软件镜像站等获得InfluxDB的RPM包&#xff0c;这里笔者下载的是influxdb-1.8.0.x86_…

STL常用容器总结

1.Vector容器特性 vector 容器是一个长度动态改变的动态数组&#xff0c;既然也是数组&#xff0c;那么其内存是一段连续的内存&#xff0c;具有数组的随机存取的优点。 / 1.1.vector特性总结: 1.vector 是动态数组&#xff0c;连续内存空间&#xff0c;具有随机存取效率高的…

BBP飞控板中的坐标系变换

一般飞控板中至少存在以下坐标系&#xff1a; 陀螺Gyro坐标系加速度计Acc坐标系磁强计Mag坐标系飞控板坐标系 在BBP飞控板采用的IMU为同时包含了陀螺&#xff08;Gyro&#xff09;及加速度计&#xff08;Acc&#xff09;的6轴传感器&#xff0c;故Gyro及Acc为同一坐标系。同时…

【OAuth2系列】如何使用OAuth 2.0实现安全授权?详解四种授权方式

作者&#xff1a;后端小肥肠 &#x1f347; 我写过的文章中的相关代码放到了gitee&#xff0c;地址&#xff1a;xfc-fdw-cloud: 公共解决方案 &#x1f34a; 有疑问可私信或评论区联系我。 &#x1f951; 创作不易未经允许严禁转载。 姊妹篇&#xff1a; 【OAuth2系列】集成微…

鸿蒙MPChart图表自定义(六)在图表中绘制游标

在鸿蒙开发中&#xff0c;MPChart 是一个非常强大的图表库&#xff0c;它可以帮助我们创建各种精美的图表。今天&#xff0c;我们将继续探索鸿蒙MPChart的自定义功能&#xff0c;重点介绍如何在图表中绘制游标。 OpenHarmony三方库中心仓 一、效果演示 以下是效果演示图&…

《新概念模拟电路》-电流源电路

电流源电路 本系列文章主要学习《新概念模拟电路》中的知识点。在工作过程中&#xff0c;碰到一些问题&#xff0c;于是又翻阅了模电这本书。我翻阅的是ADI出版的&#xff0c;西安交通大学电工中心杨建国老师编写的模电书。 本文主要是基于前文《新概念模拟电路》-三极管的基础…

Java实现下载excel模板,并实现自定义下拉框

GetMapping("excel/download")ApiOperation(value "模板下载")public void getUserRecordTemplate(HttpServletResponse response, HttpServletRequest request) throws IOException {OutputStream outputStream response.getOutputStream();InputStream…

C 实现植物大战僵尸(四)

C 实现植物大战僵尸&#xff08;四&#xff09; 音频稍卡顿问题&#xff0c;用了 SFML 三方库已优化解决 安装 SFML 资源下载 https://www.sfml-dev.org/download/sfml/2.6.2/ C 实现植物大战僵尸&#xff0c;完结撒花&#xff08;还有个音频稍卡顿的性能问题&#xff0c;待…

回归预测 | MATLAB实现CNN-BiLSTM-Attention多输入单输出回归预测

回归预测 | MATLAB实现CNN-BiLSTM-Attention多输入单输出回归预测 目录 回归预测 | MATLAB实现CNN-BiLSTM-Attention多输入单输出回归预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 一、方法概述 CNN-BiLSTM-Attention多输入单输出回归预测方法旨在通过融合CNN的局…

Ansible之批量管理服务器

文章目录 背景第一步、安装第二步、配置免密登录2.1 生成密钥2.2 分发公钥2.3 测试无密连接 背景 Ansible是Python强大的服务器批量管理 第一步、安装 首先要拉取epel数据源&#xff0c;执行以下命令 yum -y install epel-release安装完毕如下所示。 使用 yum 命令安装 an…

让css设置的更具有合理性

目录 一、合理性设置宽高 二、避免重叠情况&#xff0c;不要只设置最大宽 三、优先使用弹性布局特性 四、单词、数字换行处理 五、其他编码建议 平常写css时&#xff0c;除了遵循一些 顺序、简化、命名上的规范&#xff0c;让css具有合理性也是重要的一环。 最近的需求场…

【微服务】1、引入;注册中心;OpenFeign

微服务技术学习引入 - 微服务自2016年起搜索指数持续增长&#xff0c;已成为企业开发大型项目的必备技术&#xff0c;中高级java工程师招聘多要求熟悉微服务相关技术。微服务架构介绍 概念&#xff1a;微服务是一种软件架构风格&#xff0c;以专注于单一职责的多个响应项目为基…

设计模式 结构型 组合模式(Composite Pattern)与 常见技术框架应用 解析

组合模式&#xff08;Composite Pattern&#xff09;是一种结构型设计模式&#xff0c;它允许你将对象组合成树形结构来表示“部分-整体”的层次结构。通过这种模式&#xff0c;客户端可以一致地处理单个对象和对象组合。 在软件开发中&#xff0c;我们经常会遇到处理对象的层…

抢先体验:人大金仓数据库管理系统KingbaseES V9 最新版本 CentOS 7.9 部署体验

一、简介 KingbaseES 是中国人大金仓信息技术股份有限公司自主研发的一款通用关系型数据库管理系统&#xff08;RDBMS&#xff09;。 作为国产数据库的杰出代表&#xff0c;它专为中国市场设计&#xff0c;广泛应用于政府、金融、能源、电信等关键行业&#xff0c;以高安全性…