一命通关差分

news2024/11/18 14:42:04


 本章节是前缀和的延申

 

一命通关前缀和-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/qq_74260823/article/details/136530291?spm=1001.2014.3001.5501

 一命通关前缀和


公交车

引入

还是利用我们在前缀和中所采用的例子——公交车。

有一辆公交车,一共上下了N批乘客:

  1. 第一批2个人,第一站上车,第五站下车
  2. 第二批6个人,第三站上车,第六站下车
  3. 第三批4个人,第二站上车,第五站下车
  4. ... 

问,在不查公交车监控的情况下,公交车到达每一站的时候车上还剩下几个人?

这个问题,传统的解决方法很直接,我们创建一个数组

vector<int> platform(k),k为数组大小车站的数目

用来表示每一站的时候,车上还剩几个人。

而对每一批上下车的乘客,假设他们有people个人在第up站上车,在第off站下车,他们在车上的站数为[up,off),也就是说,数组i到j中的所有元素都要加上他们的人数people

 用以上方法,来表示前三批人:

假设有N批人,公交车一共有k站,每一批人都是第一站上最后一站下,那最坏的时间复杂度是多少?O(Nk)。有没有办法把这个解法优化一下,让每一批人的计算都变成O(1)呢?当然有:

优化

我们想让每一批人的计算都变成O(1),那就想办法,最大化利用第up站上和第off站下的信息。我们有没有办法,只需要表示第i站和第j站的人数变化,就能表示所有站的人数变化?

如果你有办法,就不会继续看这篇文章了。直接说结论吧:当然有。我们来重新挖掘一下这个信息:

  • 第up站上people人,表示公交车上从第up站开始,往后都多了people个人
  • 第off站下people人,表示公交车上从第off站开始,往后都少了people个人
  • 而在off站之后,多people个人和少people个人加在一起,最终是0个人,也就是第up站上第off站下,只对[up,off)这些站台会产生影响,对其他站台产生不了任何影响,从而得到了我们的传统解法。

我们利用这个信息,再创立一个数组:

vector<int> dif(k)

用来表示每一站和前一站的人数差dif[i]=platform[i]-platform[i-1]

而再来通过这个数组去整理题目的信息:

  • 第二站上了四个人,也就是从第二站开始,比第二站之前都要多出四个人,自然第二站比第一站要多四个人,dif[2]+=4
  • 第三站和第二站,都比第一站多四个人,第二站和第三站的差没有变化,故dif[3]不变
  • 第五站下了四个人,也就是从第五站开始,比第五站之前都要少四个人,自然第五站比第四战要少四个人,dif[5]-=4 
  • 同理,第六站和第五站的差也没有发生变化,故dif[6]不变 

通过这个,我们自然可以总结出规律:

这样,每一批的上下车,时间复杂度都优化为了O(1)

但是,有人可能就要问了,海老师海老师,这个数组有什么用啊?这又不是最终的答案
别急,往后有反转

求解 

假设,公交车有一个第0站,第0站的人数肯定是0人

  • 我们知道了第1站和第0站的人数差,第一站的人数很容易求出来platform[1]=platform[0]+dif[1] 
  • 而接着往后,第二站和第一站的人数差我们也知道,自然platform[2]=platform[1]+dif[2] 
  • 很容易便找到规律:对于每一站i,都可以求得
    platform[i]=platform[i-1]+dif[i] 

而把所有的platform展开,就能得到:
platform[i]=platform[0]+dif[1]+dif[2]+...+dif[i]\displaystyle 

也就是,platform的值为dif数组i之前所有元素的和

好了,跳出公交车。我们通过这个解答,发现platform就是前缀和数组,而对前缀和数组的每一项求差得到的dif数组,我们称之为差分数组。我们发现了platform[i]=platform[i-1]+dif[i]
platform[i]-platform[i-1]=nums[i]

也就是,dif[i]和nums[i]其实是一回事,这就是我们常说的

好了,知道这句话其实卵用没有,我们直接来看代码吧。

代码及公式

//假设一个数组 vector<int> people中有三个元素[up,off,people]
//现在给了一个二元数组 vector<vector<int>> nums,大小为n,表示有N批乘客
//求解每一站的乘客人数

//自然,初始化两个数组,platform和dif
vector<int> platform(n+1);//因为假定了一个第0站,所以多开一块空间
vector<int> dif(n+1);//差分数组

for(auto& e:nums)
{
    int up=e[0];
    int off=e[1];
    int people=e[2];
    
    dif[up]+=people;
    dif[off]-=people;
    //每一次都是O(1),一共有n次,时间复杂度为O(n)
}

//再来求前缀和
for(int i=1;i<k+1;i++)
    platform[i]=platform[i-1]+dif[i];
//时间复杂度为站台数量O(k)
//总的时间复杂度为O(n+k)

这类题目的特征在于,每一次操作都对一块区间内的所有元素进行同样的操作。
面对这样的问题,我们先用差分数组,来把这些同样的操作,只表示出其区间首尾的变化
然后对差分数组求出前缀和,就能表示出总的变化

这便是差分数组的公式。

好了,有了这个公式,去乱杀差分的题目吧:

1109. 航班预订统计 - 力扣(LeetCode)

2251. 花期内花的数目 - 力扣(LeetCode)


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

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

相关文章

SMART PLC 卷径计算(圈数检测+膜厚叠加法)

1、卷径计算(膜厚叠加+数值积分器应用博途PLC SCL代码) https://rxxw-control.blog.csdn.net/article/details/136719982https://rxxw-control.blog.csdn.net/article/details/1367199822、膜厚叠加法 https://rxxw-control.blog.csdn.net/article/details/128600466

[c++] std::future, std::promise, std::packaged_task, std::async

std::promise 进程间通信&#xff0c;std::packaged_task 任务封装&#xff0c;std::async 任务异步执行&#xff1b;std::future 获取结果。 1 std::promise 1.1 线程间同步 std::promise 可以用于线程间通信。 如下代码是 std::promise 中的示例代码。 std::promise - cp…

我的NPI项目之设备系统启动(九) -- 高通平台启动阶段和功能详解

接触到一个新的平台最终要的一件事莫过于搞清楚如何boot起系统&#xff0c;那就要弄清楚系统开机各阶段的具体工作内容。这里最好的指导就是高通的启动guide。 对于系统的镜像和启动阶段我已经做了简单的介绍&#xff0c;详见: 镜像和启动阶段的说明 那今天我就以电源为例&a…

树的初步了解及堆,堆的topk问题,堆排序

目录 前言 一&#xff1a;树 1.树的概念 2.树的基础概念知识 3.在树中孩子节点和父节点知一求一 4.树的表示方法 二&#xff1a;二叉树 1.二叉树的概念 2.二叉树的特性 3.满二叉树 4.完全二叉树 三&#xff1a;堆 1.堆的定义 2.堆的实现&#xff1a;数组实现…

牛客网-SQL大厂面试题-2.平均播放进度大于60%的视频类别

题目&#xff1a;平均播放进度大于60%的视频类别 DROP TABLE IF EXISTS tb_user_video_log, tb_video_info; CREATE TABLE tb_user_video_log (id INT PRIMARY KEY AUTO_INCREMENT COMMENT 自增ID,uid INT NOT NULL COMMENT 用户ID,video_id INT NOT NULL COMMENT 视频ID,start…

【小白刷leetcode】第15题

【小白刷leetcode】第15题 动手刷leetcode&#xff0c;正在准备蓝桥&#xff0c;但是本人算法能力一直是硬伤。。。所以做得一直很痛苦。但是不熟练的事情像练吉他一样&#xff0c;就需要慢速&#xff0c;多练。 题目描述 看这个题目&#xff0c;说实在看的不是很懂。索性我们直…

YOLOv9算法原理——使用可编程梯度信息学习想要学习的内容

前言 2023年1月发布YOLOv8正式版后&#xff0c;经过一年多的等待&#xff0c;YOLOv9终于面世了&#xff01;YOLO是一种利用图像全局信息进行目标检测的系统。自从2015年Joseph Redmon、Ali Farhadi等人提出了第一代模型以来&#xff0c;该领域的研究者们已经对YOLO进行了多次更…

OceanBase4.2版本 Docker 体验

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是【IT邦德】&#xff0c;江湖人称jeames007&#xff0c;10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】&#xff01;&#x1f61c;&am…

文件包含例子

一、常见的文件包含函数 php中常见的文件包含函数有以下四种&#xff1a; include() require() include_once() require()_once() include与require基本是相同的&#xff0c;除了错误处理方面: include()&#xff0c;只生成警告&#xff08;E_WARNING&#xff09;&#x…

Unity Live Capture 中实现面部捕捉同步模型动画

Unity Face Capture 是一个强大的工具&#xff0c;可以帮助你快速轻松地将真实人脸表情捕捉到数字模型中。在本文中&#xff0c;我们将介绍如何在 Unity Face Capture 中实现面部捕捉同步模型动画。 安装 |实时捕获 |4.0.0 (unity3d.com) 安装软件插件 安装 Live Capture 软件…

数据资产管理解决方案:构建高效、安全的数据生态体系

在数字化时代&#xff0c;数据已成为企业最重要的资产之一。然而&#xff0c;如何有效管理和利用这些数据资产&#xff0c;却是许多企业面临的难题。本文将详细介绍数据资产管理解决方案&#xff0c;帮助企业构建高效、安全的数据生态体系。 一、引言 在信息化浪潮的推动下&a…

为什么单线程的 Redis 能那么快?

大家好我是苏麟 , 给大家找一些好的文章看看 . 原文文章 : 03 高性能IO模型&#xff1a;为什么单线程Redis能那么快&#xff1f; (lianglianglee.com) Redis 为什么用单线程&#xff1f; 要更好地理解 Redis 为什么用单线程&#xff0c;我们就要先了解多线程的开销。 多线程的…

力扣hot100:416.分割等和子集(组合/动态规划/STL问题)

组合数问题 我们思考一下&#xff0c;如果要把数组分割成两个子集&#xff0c;并且两个子集的元素和相等&#xff0c;是否等价于在数组中寻找若干个数使之和等于所有数的一半&#xff1f;是的&#xff01; 因此我们可以想到&#xff0c;两种方式&#xff1a; ①回溯的方式找到t…

基于SpringBoot+Vue交流和分享平台的设计与实现(源码+部署说明+演示视频+源码介绍)

您好&#xff0c;我是码农飞哥&#xff08;wei158556&#xff09;&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。&#x1f4aa;&#x1f3fb; 1. Python基础专栏&#xff0c;基础知识一网打尽&#xff0c;9.9元买不了吃亏&#xff0c;买不了上当。 Python从入门到精通…

Android Studio实现内容丰富的安卓宠物用品商店管理系统

获取源码请点击文章末尾QQ名片联系&#xff0c;源码不免费&#xff0c;尊重创作&#xff0c;尊重劳动。 项目编号128 1.开发环境android stuido jdk1.8 eclipse mysql tomcat 2.功能介绍 安卓端&#xff1a; 1.注册登录 2.系统公告 3.宠物社区&#xff08;可发布宠物帖子&#…

如何将Git拉取项目后,将SSH验证方式修改为HTTPS?

首先在打开项目所在位置的Git BashGUI 查找当前的远程仓库URL&#xff1a; 打开终端或命令提示符&#xff0c;导航到你的项目目录&#xff0c;并使用以下命令查看当前配置的远程仓库URL&#xff1a; git remote -v这会显示如下格式的输出&#xff1a; origin gitgithub.com:用…

从政府工作报告探讨计算机行业的发展

从政府工作报告探计算机行业发展 政府工作报告作为政府工作的全面总结和未来规划&#xff0c;不仅反映了国家整体的发展态势&#xff0c;也为各行各业提供了发展的指引和参考。随着信息技术的快速发展&#xff0c;计算机行业已经成为推动经济社会发展的重要引擎之一。因此&…

什么是 KNIME Hub(2024)

什么是 KNIME Hub KNIME Hub 是一个中央存储库和协作平台&#xff0c;它是用来促进与 KNIME Analytics Platform(分析平台,AP)相关的工作流、节点、组件和扩展的共享和管理。它既充当工作流存储库又充当协作空间&#xff0c;使用户能够发现和利用可合并到其数据分析项目中的各种…

前端Prettier 插件的使用配置(详细)

各个参数代表的意思:printWidth&#xff1a;每行代码的最大长度限制。 tabWidth&#xff1a;选项用于控制制表符的宽度。 useTabs&#xff1a;指定是否使用制表符代替空格。 semi&#xff1a;指定是否在语句的末尾添加分号。 singleQuote&#xff1a;指定是否使用单引号或双引号…

控制学习_正弦波无刷直流力矩电机建模、控制带宽讨论与选择

无刷电机通过电子换向器实现定子的磁场旋转&#xff0c;去电刷后使用寿命大幅提升&#xff0c;是现在更流行的选择。三相无刷电机则是无刷电机中比较流行的一款。三相无刷电机的驱动方式有多种&#xff0c;最简单的被称为梯形波驱动、方波驱动或正弦波驱动。而正弦波驱动技术可…