LeetCode 3244.新增道路查询后的最短距离 II:贪心(跃迁合并)-9行py(O(n))

embedded/2024/11/22 20:56:46/

【LetMeFly】3244.新增道路查询后的最短距离 II:贪心(跃迁合并)-9行py(O(n))

力扣题目链接:https://leetcode.cn/problems/shortest-distance-after-road-addition-queries-ii/

给你一个整数 n 和一个二维整数数组 queries

n 个城市,编号从 0n - 1。初始时,每个城市 i 都有一条单向道路通往城市 i + 10 <= i < n - 1)。

queries[i] = [ui, vi] 表示新建一条从城市 ui 到城市 vi单向道路。每次查询后,你需要找到从城市 0 到城市 n - 1最短路径长度

所有查询中不会存在两个查询都满足 queries[i][0] < queries[j][0] < queries[i][1] < queries[j][1]

返回一个数组 answer,对于范围 [0, queries.length - 1] 中的每个 ianswer[i] 是处理完 i + 1 个查询后,从城市 0 到城市 n - 1 的最短路径的长度

 

示例 1:

输入: n = 5, queries = [[2, 4], [0, 2], [0, 4]]

输出: [3, 2, 1]

解释:

新增一条从 2 到 4 的道路后,从 0 到 4 的最短路径长度为 3。

leetcode.com%2Fuploads%2F2024%2F06%2F28%2Fimage9.jpg&pos_id=img-N5uGm0Hx-1732080025470%29" />

新增一条从 0 到 2 的道路后,从 0 到 4 的最短路径长度为 2。

leetcode.com%2Fuploads%2F2024%2F06%2F28%2Fimage10.jpg&pos_id=img-fH2gffWA-1732080027237%29" />

新增一条从 0 到 4 的道路后,从 0 到 4 的最短路径长度为 1。

示例 2:

输入: n = 4, queries = [[0, 3], [0, 2]]

输出: [1, 1]

解释:

新增一条从 0 到 3 的道路后,从 0 到 3 的最短路径长度为 1。

新增一条从 0 到 2 的道路后,从 0 到 3 的最短路径长度仍为 1。

 

提示:

  • 3 <= n <= 105
  • 1 <= queries.length <= 105
  • queries[i].length == 2
  • 0 <= queries[i][0] < queries[i][1] < n
  • 1 < queries[i][1] - queries[i][0]
  • 查询中不存在重复的道路。
  • 不存在两个查询都满足 i != jqueries[i][0] < queries[j][0] < queries[i][1] < queries[j][1]

解题方法:跃迁合并

把每一条路径视为一条跃迁通道,每个点记录“自己最多能跃迁到的点”,初始值每个点能跃迁到的点都是自己的下一个节点。

新来一条“跃迁通道”有两种可能:

  • 被一条更长(或等长)的跃迁通道覆盖
  • 覆盖n条跃迁通道

反正不可能和其他跃迁通道有交叉。

两种情况的判断方式是“跃迁起点”指向的“能跃迁到的点”是否大于(等于)自己的“跃迁终点”

例如新加一条[1, 3]的跃迁路径,结果发现1已经能跃迁到5了,那么就说明这是一条被其他“跃迁通道”覆盖的通道

  • 对于第一种情况:直接continue

  • 对于第二种情况:修改所有“最大被覆盖子跃迁通道”的起点的“能跃迁到的点”

    例如原本有“跃迁通道”[1, 3][3, 4][4, 7],新增“跃迁通道”[1, 7]

    那么就将134的“能跃迁到的点”修改为7

    跃迁次数减少 3 − 1 = 2 3-1=2 31=2

时空复杂度分析

  • 时间复杂度 O ( n + q ) O(n+q) O(n+q):每次修改一个点“能跃迁到的点”,总跃迁次数就会减少一;总跃迁次数最多减少到1,说明“跃迁合并”最多 n − 1 n-1 n1次。
  • 空间复杂度 O ( n ) O(n) O(n),返回值不计入。

AC代码

C++
/*
每个点记录“自己跃迁到的点”
初始值每个点能跃迁到的点都是自己的下一个节点新来一条“跃迁通道”有两种可能:+ 被一条更长(或等长)的跃迁通道覆盖+ 覆盖n条跃迁通道
反正不可能和其他跃迁通道有交叉
两种情况的判断方式是“跃迁起点”指向的“能跃迁到的点”是否大于(等于)自己的“跃迁终点”+ 对于第一种情况:直接continue+ 对于第二种情况:修改所有“最大被覆盖子跃迁通道”的起点的“能跃迁到的点”
*/
// FourthTry  // 简化版  // 执行用时分布:2ms,击败98.51%;消耗内存分布:108.84MB,击败83.86%.
class Solution {
public:vector<int> shortestDistanceAfterQueries(int n, vector<vector<int>>& queries) {vector<int> transitionTo(n), ans(queries.size());for (int i = 0; i < n; i++) {transitionTo[i] = i + 1;}int transitionToEndTimes = n - 1;for (int i = 0; i < queries.size(); i++) {int from = queries[i][0], to = queries[i][1], now = from;while (transitionTo[now] < to) {transitionToEndTimes--;int originalTo = transitionTo[now];transitionTo[now] = to;now = originalTo;}ans[i] = transitionToEndTimes;}return ans;}
};
Python
from typing import Listclass Solution:def shortestDistanceAfterQueries(self, n: int, queries: List[List[int]]) -> List[int]:transitionTo = [i + 1 for i in range(n)]ans = []shortestTimes = n - 1for from_, to in queries:while transitionTo[from_] < to:shortestTimes -= 1transitionTo[from_], from_ = to, transitionTo[from_]ans.append(shortestTimes)return ans
Java
class Solution {public int[] shortestDistanceAfterQueries(int n, int[][] queries) {int[] transitionTo = new int[n];for (int i = 0; i < n; i++) {transitionTo[i] = i + 1;}int[] ans = new int[queries.length];int minTimes = n - 1;for (int i = 0; i < queries.length; i++) {int from = queries[i][0], to =  queries[i][1];while (transitionTo[from] < to) {minTimes--;int originalTo = transitionTo[from];transitionTo[from] = to;from = originalTo;}ans[i] = minTimes;}return ans;}
}  // AC,100.00%,79.09%
Go
package mainfunc shortestDistanceAfterQueries(n int, queries [][]int) (ans []int) {transitionTo := make([]int, n)for i := range transitionTo {transitionTo[i] = i + 1}minTimes := n - 1for _, query := range queries {from, to := query[0], query[1]for transitionTo[from] < to {minTimes--transitionTo[from], from = to, transitionTo[from]}ans = append(ans, minTimes)}return
}  // AC,81.82%,29.41%

同步发文于CSDN和我的个人博客,原创不易,转载经作者同意后请附上原文链接哦~

Tisfy:https://letmefly.blog.csdn.net/article/details/143908539


http://www.ppmy.cn/embedded/139705.html

相关文章

甲骨文云服务器 (Oracle Cloud) 终极防封、防回收的教程!

1.WindTerm 远程终端连接器&#xff1a;【官方下载】、【备用下载 】 2.AA面板&#xff1a;【安装脚本】 3.开启端口&#xff1a; sudo iptables -P INPUT ACCEPT sudo iptables -P FORWARD ACCEPT sudo iptables -P OUTPUT ACCEPT sudo iptables -F 4.WordPress&#xf…

241117学习日志——[CSDIY] [ByteDance] 后端训练营 [05]

CSDIY&#xff1a;这是一个非科班学生的努力之路&#xff0c;从今天开始这个系列会长期更新&#xff0c;&#xff08;最好做到日更&#xff09;&#xff0c;我会慢慢把自己目前对CS的努力逐一上传&#xff0c;帮助那些和我一样有着梦想的玩家取得胜利&#xff01;&#xff01;&…

电解车间铜业机器人剥片技术是现代铜冶炼过程中自动化和智能化的重要体现

电解车间铜业机器人剥片技术是现代铜冶炼过程中自动化和智能化的重要体现 电解车间铜业机器人剥片技术是现代铜冶炼过程中自动化和智能化的重要体现&#xff0c;它主要应用于铜电解精炼的最后阶段&#xff0c;即从阴极板上剥离出纯铜的过程。以下是该技术的几个关键点&#xff…

Python Turtle召唤童年:喜羊羊与灰太狼之懒羊羊绘画

Python Turtle召唤童年&#xff1a;喜羊羊与灰太狼之懒羊羊绘画 &#x1f438; 前言 &#x1f438;&#x1f41e;往期绘画&#x1f41e;&#x1f40b; 效果图 &#x1f40b;&#x1f409; 代码 &#x1f409; &#x1f438; 前言 &#x1f438; 小时候&#xff0c;每次打开电视…

Linux 定时任务全解析

文章目录 一、Cron 服务1.1安装1.2配置文件格式1.3使用方法1.4系统级与用户级 Cron 任务区别 二、At 服务2.1安装2.2工作原理2.3使用方法 一、Cron 服务 1.1安装 在大多数 Linux 发行版中&#xff0c;Cron 服务通常已经默认安装。例如在 Ubuntu 系统中&#xff0c;可以通过以…

.NET 简介

文章目录 一、组件二、免费且开源三、支持四、.NET 生态系统 .NET 是一个免费的跨平台开放源代码开发人员平台&#xff0c;用于生成多种类型的应用程序。 .NET 可以运行使用多种语言编写的程序&#xff0c;其中 C# 是最常用的语言。 .NET 依赖于许多大规模应用在生产中使用的高…

【网络安全 | 漏洞挖掘】邮件HTML注入

文章目录 Email 中的 HTML 注入漏洞漏洞挖掘过程1. 初步信息收集2. 发现私信功能3. 功能测试与 HTML 注入测试测试步骤请求拦截与分析4. 绕过防护机制绕过方法附加威胁漏洞影响漏洞报告与奖励Email 中的 HTML 注入漏洞 HTML 注入是一种安全漏洞,攻击者通过将任意 HTML 标签注…

vue中路由缓存

vue中路由缓存 问题描述及截图解决思路关键代码及打印信息截图 问题描述及截图 在使用某一平台时发现当列表页码切换后点击某一卡片进入详情页后&#xff0c;再返回列表页时页面刷新了。这样用户每次看完详情回到列表页都得再重新输入自己的查询条件&#xff0c;或者切换分页到…