算法解析:LeetCode——机器人碰撞和最低票价
摘要:本文由葡萄城技术团队原创并首发。转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具、解决方案和服务,赋能开发者。
机器人碰撞
问题:
现有 n 个机器人,编号从 1 开始,每个机器人包含在路线上的位置、健康度和移动方向。 给你下标从 0 开始的两个整数数组 positions、healths 和一个字符串 directions(directions[i] 为 ‘L’ 表示 向左 或 ‘R’ 表示 向右)。positions 中的所有整数 互不相同 。 所有机器人以相同速度同时沿给定方向在路线上移动。如果两个机器人移动到相同位置,则会发生 碰撞 。 如果两个机器人发生碰撞,则将 健康度较低 的机器人从路线中 移除 ,并且另一个机器人的健康度 减少 1 。 幸存下来的机器人将会继续沿着与之前 相同 的方向前进。如果两个机器人的健康度相同,则将二者都从路线中移除。 请你确定全部碰撞后幸存下的所有机器人的 健康度 ,并按照原来机器人编号的顺序排列。 即机器人 1 (如果幸存)的最终健康度,机器人 2 (如果幸存)的最终健康度等。 如果不存在幸存的机器人,则返回空数组。 在不再发生任何碰撞后,请你以数组形式,返回所有剩余机器人的健康度(按机器人输入中的编号顺序)。
示例 :
输入:positions = [3,5,2,6], healths = [10,10,15,12], directions = “RLRL” 输出:[14] 解释:本例中发生 2 次碰撞。首先,机器人 1 和机器人 2 将会碰撞,因为二者健康度相同,二者都将被从路线中移除。接下来,机器人 3 和机器人 4 将会发生碰撞,由于机器人 4 的健康度更小,则它会被移除,而机器人 3 的健康度变为 15 - 1 = 14 。仅剩机器人 3 ,所以返回 [14] 。
提示: 1 <= positions.length == healths.length == directions.length == n <= 105 1 <= positions[i], healths[i] <= 109 directions[i] == ‘L’ 或 directions[i] == ‘R’ positions 中的所有值互不相同。
解决思路
用一个栈存放当前存活的机器人,按位置从左至右(排序后的下标)遍历机器人并判断当前机器人的方向:
1. 如果当前机器人方向是 R,当前机器人推入栈,继续处理下一个机器人;
2.如果方向是 L:
(1)如果栈为空,当前机器人推入栈,继续处理下一个机器人;
(2) 如果栈顶元素方向也是 L,当前机器人推入栈,继续处理下一个机器人;
(3) 比较与栈顶元素的健康度,判断存活哪个:
- 如果栈顶存活,栈顶机器人健康度减 1,继续处理下一个机器人;
- 如果当前存活,栈顶弹出,当前机器人健康度减 1,回到 2.3 ;
- 如果两个都消失,栈顶弹出,继续处理下一个机器人。
3.最后,按position顺序返回stack 中的健康度即可。
代码(JavaScript)
function survivedRobotsHealths(positions: number[], healths: number[], directions: string) : number[] {//用一个栈存放当前存活的机器人let stack: robot[] = [];interface robot {i: number;p: number;h: number;d: string;}let robots: robot[] = [];//从左至右(排序后的下标)遍历机器人并判断当前机器人的方向positions.forEach((v, i) = >robots.push({i: i,p: v,h: healths[i],d: directions[i]}));robots.sort((a, b) = >a.p - b.p);for (let i = 0; i < robots.length;) {/**比较与栈顶元素的健康度,判断存活哪个: 1.如果栈顶存活,栈顶机器人健康度减 1,继续处理下一个机器人;2.如果当前存活,栈顶弹出,当前机器人健康度减 1,回到 2.3 ;3.如果两个都消失,栈顶弹出,继续处理下一个机器人。**/if (stack.length === 0 || robots[i].d === 'R' || (robots[i].d === 'L' && stack[stack.length - 1].d === 'L')) {stack.push(robots[i++]);} else if (stack[stack.length - 1].h === robots[i].h) {stack.pop();i++;} else if (stack[stack.length - 1].h > robots[i].h) {stack[stack.length - 1].h--;i++;} else if (stack[stack.length - 1].h < robots[i].h) {stack.pop();robots[i].h--;}} // console.log(stack);stack.sort((a, b) => a.i - b.i); let ans = []; stack.forEach(v=> ans.push(v.h)); return ans; };
最低票价
问题:
在一个火车旅行很受欢迎的国度,你提前一年计划了一些火车旅行。在接下来的一年里,你要旅行的日子将以一个名为 days 的数组给出。 每一项是一个从 1 到 365 的整数。
火车票有 三种不同的销售方式 :
- 一张 为期一天 的通行证售价为 costs[0] 美元;
- 一张 为期七天 的通行证售价为 costs[1] 美元;
- 一张 为期三十天 的通行证售价为 costs[2] 美元。
通行证允许数天无限制的旅行。 例如,如果我们在第 2 天获得一张 为期 7 天 的通行证,那么我们可以连着旅行 7 天:第 2 天、第 3 天、第 4 天、第 5 天、第 6 天、第 7 天和第 8 天。 返回 你想要完成在给定的列表 days 中列出的每一天的旅行所需要的最低消费 。
示例 1:
输入:days = [1,4,6,7,8,20], costs = [2,7,15]
输出:11
解释: 例如,这里有一种购买通行证的方法,可以让你完成你的旅行计划: 在第 1 天,你花了 costs[0] = $2 买了一张为期 1 天的通行证,它将在第 1 天生效。 在第 3 天,你花了 costs[1] = $7 买了一张为期 7 天的通行证,它将在第 3, 4, …, 9 天生效。 在第 20 天,你花了 costs[0] = $2 买了一张为期 1 天的通行证,它将在第 20 天生效。 你总共花了 $11,并完成了你计划的每一天旅行。
示例 2:
输入:days = [1,2,3,4,5,6,7,8,9,10,30,31], costs = [2,7,15]
输出:17
解释: 例如,这里有一种购买通行证的方法,可以让你完成你的旅行计划: 在第 1 天,你花了 costs[2] = $15 买了一张为期 30 天的通行证,它将在第 1, 2, …, 30 天生效。 在第 31 天,你花了 costs[0] = $2 买了一张为期 1 天的通行证,它将在第 31 天生效。 你总共花了 $17,并完成了你计划的每一天旅行。
提示:
- 1 <= days.length <= 365
- 1 <= days[i] <= 365
- days 按顺序严格递增
- costs.length == 3
- 1 <= costs[i] <= 1000
解决思路
代码(JavaScript)
1.暴力递归解法:
//暴力递归解法
function mincostTickets(days: number[], costs: number[]) : number { return costday(days, costs, 1);
};
function costday(days: number[], costs: number[], day: number) : number { if (day > days[days.length - 1]) { return 0; } if (day == days[days.length - 1]) { return Math.min(...costs); } if (!days.includes(day)) { return costday(days, costs, day + 1); } else { return Math.min( costday(days, costs, day + 1) + costs[0], costday(days, costs, day + 7) + costs[1], costday(days, costs, day + 30) + costs[2], ) }
};
问题:
此解法存在重叠子问题和最优子结构
重叠子问题就是F(n)会重复计算,上图中同色的结点
最优子结构就是F(n)的解,可以由子问题F(n+1),F(n+7),F(n+30)的解得到
解决方案:
记录每个子问题f(n)的解,如果后面的计算又要用f(n),则直接取计算结果,避免重复计算:
function mincostTickets(days: number[], costs: number[]) : number { let fn = []; return costday(days, costs, 1, fn);
};function costday(days: number[], costs: number[], day: number, fn: number[]) : number { if (day > days[days.length - 1]) { return 0; } if (day == days[days.length - 1]) { if (!fn[day]) { fn[day] = Math.min(...costs); } return fn[day]; } if (!days.includes(day)) { if (!fn[day]) { fn[day] = costday(days, costs, day + 1, fn); } return fn[day]; } else { if (!fn[day]) { fn[day] = Math.min( costday(days, costs, day + 1, fn) + costs[0], costday(days, costs, day + 7, fn) + costs[1], costday(days, costs, day + 30, fn) + costs[2], ) } return fn[day];}
};
2.动态规划,自底向上解法
将前面的F(n)换为dp[n],表示从第n天开始后,总共的花费,dp[1]即是问题的解,F(n)是从前往后算,dp是从后往前算,消除递归。
function mincostTickets(days: number[], costs: number[]) : number { const lastDay = days[days.length - 1]; let dp = new Array(lastDay + 30 + 1).fill(0); for (let i = lastDay; i >= 1; i--) { if (days.includes(i)) {//此处还可以优化,将所有days放到set中判断day是否存在dp[i] = Math.min(dp[i + 1] + costs[0], dp[i + 7] + costs[1], dp[i + 30] + costs[2]); } else { dp[i] = dp[i + 1]; } } return dp[1];
};
总结
以上就是机器人碰撞和最低票价两个问题的解法,除此之外,如果您想了解更多关于JavaScript的资料,欢迎访问这篇学习指南,无论是初学者还是有经验的专业人士,该帮助手册都将为您提供有价值的指导和帮助。
扩展链接:
从表单驱动到模型驱动,解读低代码开发平台的发展趋势
低代码开发平台是什么?
基于分支的版本管理,帮助低代码从项目交付走向定制化产品开发
相关文章:

算法解析:LeetCode——机器人碰撞和最低票价
摘要:本文由葡萄城技术团队原创并首发。转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具、解决方案和服务,赋能开发者。 机器人碰撞 问题: 现有 n 个机器人,编号从 1 开始,每个…...

LeetCode刷题总结 - LeetCode 热题 100 - 持续更新
LeetCode 热题 100 其他系列哈希1. 两数之和49. 字母异位词分组128. 最长连续序列 双指针27. 移除元素283. 移动零11. 盛最多水的容器剑指 Offer II 007. 数组中和为 0 的三个数42. 接雨水 滑动窗口438. 找到字符串中所有字母异位词3. 无重复字符的最长子串 字串560. 和为 K 的…...

Spring是什么?为什么要使用Spring?
目录 前言 一、Spring是什么? 1.1 轻量级 1.2 JavaEE的解决方案 二、为什么要使用Spring 2.1 传统方式完成业务逻辑 2.2 使用Spring模式完成业务逻辑 三、为什么使用Spring? 前言 本文主要介绍Spring是什么,并且解释为何要去使用Spring&…...

自我监督学习日志
学习日志 10.12 一天学不了一分钟,不知道为什么也就是了 今天一定要学一个小时! 机器学习就是机器帮我们找一个函数 语音辨识,语音,声音讯号 转化为文字 帮我们找一个人类写不出来的复杂函数 类神经网络 输入 一张图片用一个矩…...
配置CA证书
前置条件 配置Java环境变量。 具体操作 windows环境 以管理员方式执行CMD窗口,输入命令; cd /d %JAVA_HOME%\jre\lib\securitycurl -kv https://xxx/artifactory/CMC-Release/certificates/xxxRootCA.cer -o xxxRootCA.cercurl -kv https://xxx/art…...

计算机毕业设计选什么题目好?springboot 高校就业管理系统
✍✍计算机编程指导师 ⭐⭐个人介绍:自己非常喜欢研究技术问题!专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目:有源码或者技术上的问题欢迎在评论区一起讨论交流! ⚡⚡ Java实战 |…...

上海-华为全联接大会|竹云受邀参加华为云ROMAConnect行业生态联盟成立联合发布会
2023年9月22日,在上海举办的华为全联接大会上,竹云作为华为云全方位合作伙伴代表,受邀参加华为云ROMAConnect行业生态联盟成立联合发布会。华为云PaaS服务产品部副部长张甲磊以及联盟主要成员企业出席发布仪式,共同见证华为云ROMA…...
走进GraalVM
是什么 GraalVM是一个高性能的JDK,旨在加速用Java和其他JVM语言编写的应用程序的执行,同时还为JavaScript,Python,Ruby和许多其他流行语言提供运行特点 GraalVM可以代替JDK、JVM之前的工作。 GraalVM除了支持Java,也支…...

spark读取hive表字段,区分大小写问题
背景 spark任务读取hive表,查询字段为小写,但Hive表字段为大写,无法读取数据 问题错误: 如何解决呢? In version 2.3 and earlier, when reading from a Parquet data source table, Spark always returns null for any column …...
UE4和C++ 开发-头文件(.h) 和实现文件(.cpp)区别
.h文件和.cpp文件是C程序中的两种不同类型的文件。 .h文件通常包含类、函数和变量的声明, 而.cpp文件包含这些声明的实现。 .h文件中的声明通常是公共的,可以被其他文件包含和使用。.cpp文件中的实现通常是私有的,只能在该文件中使用。 在…...

git介绍和安装、(git,github,gitlab,gitee介绍)、git工作流程、git常用命令、git忽略文件
1 git介绍和安装 2 git,github,gitlab,gitee介绍 3 git工作流程 4 git常用命令 5 git忽略文件 1 git介绍和安装 首页功能写完了---》正常应该提交到版本仓库---》大家都能看到这个---》 运维应该把现在这个项目部署到测试环境中---》测试…...

go cpu、内存监控、性能分析:PProf
PProf PProf 是什么 PProf是 golang 官方提供的性能调优分析工具,用于分析和优化Go程序的性能。 PProf通过收集和分析程序的运行时数据来生成性能分析报告。它使用Go语言的运行时特性,如代码注释和特殊的程序运行标记,来收集性能数据。PPr…...

计算机网络传输层知识总结·
传输层提供的服务 传输层的功能 ●传输层提供进程之间的逻辑通信,即端到端的通信 ●复用和分用 ●差错检测(首部和数据部分) ●面向连接的TCP和无连接的UDP 端口的作用 ●端口标识的是主机中的进程 ●硬件端口是不同…...
vue使用ant design Vue中的a-select组件实现下拉分页加载数据
<a-form-model-item :labelCol"labelCol" :wrapperCol"wrapperCol" prop"equipmentTypeId" label"所属设备种类"> <a-select v-model"model.equipmentTypeId" popupScroll"handlePopupScroll" placehold…...

精准突击!GitHub星标103k,2023年整理1658页JAVA秋招面试题
前言: 现在的互联网开发岗招聘,程序员面试背八股文已经成为了不可逆转的形式,其中一个Java岗几百人在投简历也已经成为了常态!更何况一份面试题动辄七八百道,你吃透了,技术只要不是很差,面试怎…...

GEE:基于GLDAS数据集分析土壤湿度的时间序列变化
作者:CSDN @ _养乐多_ 本篇博客将介绍如何使用Google Earth Engine(GEE)进行土壤湿度数据的分析。我们将使用NASA GLDAS(Global Land Data Assimilation System)数据集,其中包括了关于土壤湿度的信息。通过该数据集,我们将了解土壤湿度在特定区域和时间段内的变化,并生…...

Nacos安装
Nacos安装 1.Windows安装 1.1.下载安装包 在Nacos的GitHub页面,提供有下载链接,可以下载编译好的Nacos服务端或者源代码: GitHub主页:https://github.com/alibaba/nacos GitHub的Release下载页:https://github.co…...

UE4和C++ 开发-C++与UMG的交互2(C++获取UMG的属性)
1、...C获取UMG的属性 1.1、第一种方法:通过名称获取控件。 void UMyUserWidget::NativeConstruct() {Super::NativeConstruct();//通过名字,获取蓝图控件中的按钮引用。CtnClic Cast<UButton>(GetWidgetFromName(TEXT("Button_44"))…...

Ubuntu 22.04.3 LTS单机私有化部署sealos
推荐使用奇数台 Master 节点和若干 Node 节点操作系统 :Ubuntu 22.04 LTS内核版本 :5.4 及以上配置推荐 :CPU 4 核 , 内存 8GB, 存储空间 100GB 以上最小配置 :CPU 2 核 , 内存 4GB, 存储空间 60GB 这里采用的Ubuntu 22.04.3 LTS 版本,Ubuntu 20.04.4 LTS这个版本…...
#力扣:2236. 判断根结点是否等于子结点之和@FDDLC
2236. 判断根结点是否等于子结点之和 一、Java /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val val; }* TreeNode(int val, TreeNo…...
MVC 数据库
MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...
大模型多显卡多服务器并行计算方法与实践指南
一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...
【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案
目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后,迭代器会失效,因为顺序迭代器在内存中是连续存储的,元素删除后,后续元素会前移。 但一些场景中,我们又需要在执行删除操作…...
SpringAI实战:ChatModel智能对话全解
一、引言:Spring AI 与 Chat Model 的核心价值 🚀 在 Java 生态中集成大模型能力,Spring AI 提供了高效的解决方案 🤖。其中 Chat Model 作为核心交互组件,通过标准化接口简化了与大语言模型(LLM࿰…...
boost::filesystem::path文件路径使用详解和示例
boost::filesystem::path 是 Boost 库中用于跨平台操作文件路径的类,封装了路径的拼接、分割、提取、判断等常用功能。下面是对它的使用详解,包括常用接口与完整示例。 1. 引入头文件与命名空间 #include <boost/filesystem.hpp> namespace fs b…...

PLC入门【4】基本指令2(SET RST)
04 基本指令2 PLC编程第四课基本指令(2) 1、运用上接课所学的基本指令完成个简单的实例编程。 2、学习SET--置位指令 3、RST--复位指令 打开软件(FX-TRN-BEG-C),从 文件 - 主画面,“B: 让我们学习基本的”- “B-3.控制优先程序”。 点击“梯形图编辑”…...
CentOS 7.9安装Nginx1.24.0时报 checking for LuaJIT 2.x ... not found
Nginx1.24编译时,报LuaJIT2.x错误, configuring additional modules adding module in /www/server/nginx/src/ngx_devel_kit ngx_devel_kit was configured adding module in /www/server/nginx/src/lua_nginx_module checking for LuaJIT 2.x ... not…...
Python打卡训练营学习记录Day49
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...