Leetcode打卡:新增道路查询后的最短距离II

news2024/11/24 8:27:49

执行结果:通过

题目:3244 新增道路查询后的最短距离II

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

有 n 个城市,编号从 0 到 n - 1。初始时,每个城市 i 都有一条单向道路通往城市 i + 1( 0 <= 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。

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

新增一条从 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 != j 且 queries[i][0] < queries[j][0] < queries[i][1] < queries[j][1]

代码以及解题思路

代码:

class Solution:
    def shortestDistanceAfterQueries(self, n: int, queries: List[List[int]]) -> List[int]:
        st = LazySegmentTree(n)
        ans = []
        for l, r in queries:
            st.update(1,1,n,l+2,r, 0)
            ans.append(st.cnt[1]-1)
        return ans




class LazySegmentTree:
    def __init__(self, n: int):
        self.cnt = [0] * (4 * n)
        self.todo = [-1] * (4 * n)
        self.build(1,1,n)

    # 初始化线段树   o,l,r=1,1,n
    def build(self, o: int, l: int, r: int) -> None:
        if l == r:
            self.cnt[o] = 1
            return
        m = (l + r) >> 1
        self.build(o * 2, l, m)
        self.build(o * 2 + 1, m + 1, r)
        self.maintain(o)

    def maintain(self, o: int) -> None:
        self.cnt[o] = self.cnt[o * 2] + self.cnt[o * 2 + 1]

    def do(self, o: int, val: int) -> None:
        self.cnt[o] = val
        self.todo[o] = val

    def spread(self, o: int) -> None:
        v = self.todo[o]
        if v == 0:
            self.do(o * 2, v)
            self.do(o * 2 + 1, v)
            self.todo[o] = -1

   
    def update(self, o: int, l: int, r: int, L: int, R: int, val: int) -> None:
        if L <= l and r <= R:
            self.do(o, val)
            return
        self.spread(o)
        m = (l + r) >> 1
        if m >= L:
            self.update(o * 2, l, m, L, R, val)
        if m < R:
            self.update(o * 2 + 1, m + 1, r, L, R, val)
        self.maintain(o)

    def query(self, o: int, l: int, r: int, L: int, R: int) -> int:
        if L <= l and r <= R:
            return self.cnt[o]
        self.spread(o)
        m = (l + r) >> 1
        res = 0
        if L <= m:
            res = self.query(o * 2, l, m, L, R)
        if m < R:
            res = max(res, self.query(o * 2 + 1, m + 1, r, L, R))
        return res

        

解题思路:

  1. 初始化线段树
    • 创建一个 LazySegmentTree 实例,其大小为 4n(因为线段树通常需要一个额外的空间来存储内部节点)。
    • 初始化 cnt 数组来存储每个节点的区间内未访问元素的数量。
    • 初始化 todo 数组来存储延迟的更新操作。
    • 调用 build 方法来构建线段树,初始时所有元素都是未访问的,所以每个叶子节点的 cnt 值都设为 1(表示该位置是未访问的)。
  2. 处理查询
    • 对于每个查询 (l, r),调用 update 方法将索引从 l+2 到 r(注意这里的 l+2 是因为题目可能有特定的索引约定,比如索引 0 和 1 被视为特殊情况,或者为了避免边界问题)之间的所有元素标记为已访问(即将其 cnt 值更新为 0)。
    • 在每次更新后,通过查看根节点的 cnt 值(即整个数组的未访问元素数量)减 1 来计算最近的未访问元素与数组起始位置的距离。这是因为每次更新都会使得一个元素从未访问变为已访问,而根节点的 cnt 值反映了整个数组中未访问元素的数量。减 1 是因为索引是从 0 开始的,而我们需要的是距离,所以需要将计数器的值转换为实际的索引距离(这里假设数组中的元素是连续排列的,没有空缺)。
  3. 线段树的操作
    • build 方法用于构建线段树,初始化每个叶子节点的 cnt 值。
    • maintain 方法用于维护节点的 cnt 值,确保它反映了其子节点的 cnt 值之和。
    • do 方法用于立即更新节点的 cnt 值和 todo 值。
    • spread 方法用于将延迟的更新操作传播到子节点。
    • update 方法用于执行区间更新操作,使用延迟技术来优化性能。
    • query 方法虽然在这段代码中未使用,但通常用于查询区间内的某些信息(如最大值、最小值等)。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

在 CentOS 系统上直接安装 MongoDB 4.0.25

文章目录 步骤 1&#xff1a;配置 MongoDB 官方源步骤 2&#xff1a;安装 MongoDB步骤 3&#xff1a;启动 MongoDB 服务步骤 4&#xff1a;验证安装步骤 5&#xff1a;可选配置注意事项 以下是在 CentOS 系统上直接安装 MongoDB 4.0.25 的详细步骤&#xff1a; 步骤 1&#x…

商城小程序的流程渠道拓展

传统印象里&#xff0c;小程序的开发制作似乎很难&#xff0c;尤其是商城类型且功能体系完善的&#xff0c;事实也确实如此&#xff0c;没有较高的技术和成本投入或团队各个流程的专业人员合作&#xff0c;很难开发出来成品&#xff0c;或者质量较低。 当然对于大公司来说&…

计算机网络 (5)数据通信的基础知识

前言 数据通信是一种以信息处理技术和计算机技术为基础的通信方式&#xff0c;它通过数据通信系统将数据以某种信号方式从一处传送到另一处&#xff0c;为计算机网络的应用和发展提供了技术支持和可靠的通信环境&#xff0c;是现代通信技术的关键部分。 一、数据通信的基本概念…

《云计算网络技术与应用》实训5-1:OpenvSwitch环境安装及常用操作练习

文章目录 OpenvSwitch环境安装及常用操作1. 使用VMware安装CentOS 7虚拟机&#xff0c;安装时需添加多一张网卡&#xff0c;该网卡为自定义-VMnet1.并且记得开启CPU虚拟化&#xff0c;将其命名为“OVS1”。2. 安装完虚拟机后&#xff0c;进入虚拟机&#xff0c;修改网络配置&am…

用指针遍历数组

#include<stdio.h> int main() {//定义一个二维数组int arr[3][4] {{1,2,3,4},{2,3,4,5},{3,4,5,6},};//获取二维数组的指针int (*p)[4] arr;//二维数组里存的是一维数组int[4]for (int i 0; i < 3; i){//遍历一维数组for (int j 0; j <4; j){printf("%d &…

07架构面试题

目录 一、关于合生元的面试题的架构分析的问题 1. 陈述两种方案的优劣 2. 在那些条件下&#xff0c;会选择哪一个方案 3. 你倾向那一种&#xff1f; 4. 如果要实施方案二的&#xff0c;准备步骤和流程 一、关于合生元的面试题的架构分析的问题 1. 陈述两种方案的优劣 方案…

【Word】一键批量引用论文上标——将正文字体改为上标格式

【Word】一键批量引用论文上标——将正文字体改为上标格式 写在最前面Word一键批量引用论文上标技巧分享核心思路&#xff1a;Word 替换功能 通配符步骤详解1. 打开 Word 替换功能2. 输入通配符模式3. 设置替换格式为上标4. 批量替换 实际效果展示技巧扩展 &#x1f308;你好呀…

C代码编写中 `fileno` 的作用

C代码编写中 `fileno` 的作用 一、`fileno` 的作用二、使用场景三、在C代码中使用 `fileno`四、总结在C语言编程中,fileno 函数是一个非常重要的工具,它在处理文件I/O操作时发挥了关键作用。本文将详细介绍 fileno 的作用、使用场景以及如何在C代码中使用它。 一、fileno 的作…

基于xr-frame实现微信小程序的手部、手势识别3D模型叠加和石头剪刀布游戏功能

前言 xr-frame是一套小程序官方提供的XR/3D应用解决方案&#xff0c;基于混合方案实现&#xff0c;性能逼近原生、效果好、易用、强扩展、渐进式、遵循小程序开发标准。xr-frame在基础库v2.32.0开始基本稳定&#xff0c;发布为正式版&#xff0c;但仍有一些功能还在开发&#…

使用大语言模型创建 Graph 数据

Neo4j 是开源的 Graph 数据库&#xff0c;Graph 数据通过三元组进行表示&#xff0c;两个顶点一条边&#xff0c;从语意上可以理解为&#xff1a;主语、谓语和宾语。GraphDB 能够通过图来表达复杂的结构&#xff0c;非常适合存储知识型数据&#xff0c;本文将通过大语言实现图数…

Stable diffusion详细讲解

&#x1f33a;系列文章推荐&#x1f33a; 扩散模型系列文章正在持续的更新&#xff0c;更新节奏如下&#xff0c;先更新SD模型讲解&#xff0c;再更新相关的微调方法文章&#xff0c;敬请期待&#xff01;&#xff01;&#xff01;&#xff08;本文及其之前的文章均已更新&…

数字化那点事:一文读懂物联网

一、物联网是什么&#xff1f; 物联网&#xff08;Internet of Things&#xff0c;简称IoT&#xff09;是指通过网络将各种物理设备连接起来&#xff0c;使它们可以互相通信并进行数据交换的技术系统。通过在物理对象中嵌入传感器、处理器、通信模块等硬件&#xff0c;IoT将“…

(图解)TCP的三次握手,四次挥手

文章目录 1. TCP包头结构1.1固定部分字段1.2 可变选项部分字段 2. TCP的三次握手与四次挥手2.1 服务器端状态转换2.2 客户端状态转换 3. TCP的状态转换图一、状态说明二、状态转换 1. TCP包头结构 TCP(Transmission Control Protocol)传输控制协议是一种面向连接的、可靠的、基…

opencv(c++)----图像的读取以及显示

opencv(c)----图像的读取以及显示 imread: 作用&#xff1a;读取图像文件并将其加载到 Mat 对象中。参数&#xff1a; 第一个参数是文件路径&#xff0c;可以是相对路径或绝对路径。第二个参数是读取标志&#xff0c;比如 IMREAD_COLOR 表示以彩色模式读取图像。 返回值&#x…

GIT 入门详解指南

前言&#xff1a; 注&#xff1a;本博客仅用于记录本人学习过程中对git的理解&#xff0c;仅供学习参考&#xff0c;如有异议请自行查资料求证 安装 使用git之前必须完成git的安装&#xff0c;Git 目前支持 Linux/Unix、Solaris、Mac和 Windows 平台上运行 git 安装教程 基本…

基于YOLOv8深度学习的违法暴力行为检测系统研究与实现(PyQt5界面+数据集+训练代码)

本研究提出了一种基于YOLOV8深度学习模型的违法暴力行为检测系统&#xff0c;并结合PyQt5框架实现了一个直观且易于操作的用户界面。随着监控系统在公共场所的广泛应用&#xff0c;如何快速、准确地识别并检测视频中的暴力和违法行为已成为当今公共安全管理中的重要挑战。现有的…

Flutter:RotationTransition旋转动画

配置vsync&#xff0c;需要实现一下with SingleTickerProviderStateMixinclass _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin{// 定义 AnimationController late AnimationController _controller;overridevoid initState() {super…

Java基础知识(六)

文章目录 StringString、StringBuffer、StringBuilder 的区别&#xff1f;String 为什么是不可变的?字符串拼接用“” 还是 StringBuilder?String#equals() 和 Object#equals() 有何区别&#xff1f;字符串常量池的作用了解吗&#xff1f;String s1 new String("abc&qu…

微积分复习笔记 Calculus Volume 1 - 6.3 Volumes of Revolution: Cylindrical Shells

6.3 Volumes of Revolution: Cylindrical Shells - Calculus Volume 1 | OpenStax

开源在线聊天系统Fiora本地Docker快速搭建并实现与好友远程聊天

文章目录 前言1.关于Fiora2.安装Docker3.本地部署Fiora4.使用Fiora5.cpolar内网穿透工具安装6.创建远程连接公网地址7.固定Uptime Kuma公网地址 前言 相信大家在聊天时候总是很没安全感&#xff0c;比如在和小姐妹背着男朋友聊一些不能说的坏话&#xff0c;或者背着女朋友和兄…