leetcode1801. 积压订单中的订单总数

news2024/11/16 23:30:01

给你一个二维整数数组 orders ,其中每个 orders[i] = [pricei, amounti, orderTypei] 表示有 amounti 笔类型为 orderTypei 、价格为 pricei 的订单。

订单类型 orderTypei 可以分为两种:

  • 0 表示这是一批采购订单 buy
  • 1 表示这是一批销售订单 sell

注意,orders[i] 表示一批共计 amounti 笔的独立订单,这些订单的价格和类型相同。对于所有有效的 i ,由 orders[i] 表示的所有订单提交时间均早于 orders[i+1] 表示的所有订单。

存在由未执行订单组成的 积压订单 。积压订单最初是空的。提交订单时,会发生以下情况:

  • 如果该订单是一笔采购订单 buy ,则可以查看积压订单中价格 最低 的销售订单 sell 。如果该销售订单 sell 的价格 低于或等于 当前采购订单 buy 的价格,则匹配并执行这两笔订单,并将销售订单 sell 从积压订单中删除。否则,采购订单 buy 将会添加到积压订单中。
  • 反之亦然,如果该订单是一笔销售订单 sell ,则可以查看积压订单中价格 最高 的采购订单 buy 。如果该采购订单 buy 的价格 高于或等于 当前销售订单 sell 的价格,则匹配并执行这两笔订单,并将采购订单 buy 从积压订单中删除。否则,销售订单 sell 将会添加到积压订单中。

输入所有订单后,返回积压订单中的 订单总数 。由于数字可能很大,所以需要返回对 109 + 7 取余的结果。

示例1:

输入:orders = [[10,5,0],[15,2,1],[25,1,1],[30,4,0]]
输出:6
解释:输入订单后会发生下述情况:
- 提交 5 笔采购订单,价格为 10 。没有销售订单,所以这 5 笔订单添加到积压订单中。
- 提交 2 笔销售订单,价格为 15 。没有采购订单的价格大于或等于 15 ,所以这 2 笔订单添加到积压订单中。
- 提交 1 笔销售订单,价格为 25 。没有采购订单的价格大于或等于 25 ,所以这 1 笔订单添加到积压订单中。
- 提交 4 笔采购订单,价格为 30 。前 2 笔采购订单与价格最低(价格为 15)的 2 笔销售订单匹配,从积压订单中删除这 2 笔销售订单。第 3 笔采购订单与价格最低的 1 笔销售订单匹配,销售订单价格为 25 ,从积压订单中删除这 1 笔销售订单。积压订单中不存在更多销售订单,所以第 4 笔采购订单需要添加到积压订单中。
最终,积压订单中有 5 笔价格为 10 的采购订单,和 1 笔价格为 30 的采购订单。所以积压订单中的订单总数为 6 。
/**
 * @param {number[][]} orders
 * @return {number}
 */
var getNumberOfBacklogOrders = function(orders) {
    let mod = 1000000007
    let buy = new MaxPriorityQueue({ priority: (bid) => bid.price })
    let sell = new MinPriorityQueue({ priority: (bid) => bid.price })
    let total = 0
    for(let [price, amount, orderType] of orders) {
        if (orderType === 0) { // 买 找卖小
          while (!sell.isEmpty() && sell.front().priority <= price && amount > 0) {
              let head = sell.dequeue().element
              if (amount < head.amount) {
                sell.enqueue({price: head.price, amount: head.amount - amount})
                total -= amount
                amount = 0
              } else {
                amount -= head.amount
                total -= head.amount
              }
          }
          if (amount > 0) buy.enqueue({price, amount}), total += amount
        } else {// 卖  找买大
          while (!buy.isEmpty() && buy.front().priority >= price && amount > 0)  {
            let head = buy.dequeue().element
            if (amount < head.amount) {
                buy.enqueue({price: head.price, amount: head.amount - amount})
                total -= amount
                amount = 0
              } else {
                amount -= head.amount
                total -= head.amount
              }
          }
          if (amount > 0) sell.enqueue({price, amount}), total += amount
        }
    }
    return total % mod
};
 

代码解读:使用了两个优先队列:buysellbuy队列用于存储购买订单,按价格降序排列;sell队列用于存储出售订单,按价格升序排列。这样可以快速找到匹配的订单。

接下来,我们逐行分析代码:

  1. let mod = 1000000007:定义一个模数,用于计算结果时取模,防止整数溢出。
  2. let buy = new MaxPriorityQueue({ priority: (bid) => bid.price }):创建一个最大优先级队列buy,用于存储购买订单,按价格降序排列。
  3. let sell = new MinPriorityQueue({ priority: (bid) => bid.price }):创建一个最小优先级队列sell,用于存储出售订单,按价格升序排列。
  4. let total = 0:初始化总订单数量为0。 5-26. 遍历orders数组中的每个订单:
    • 如果订单类型为0(购买),则尝试与sell队列中的价格较低的出售订单匹配。如果匹配成功,更新剩余数量和总订单数量。如果没有完全匹配,将剩余的购买订单加入buy队列。
    • 如果订单类型为1(出售),则尝试与buy队列中的价格较高的购买订单匹配。如果匹配成功,更新剩余数量和总订单数量。如果没有完全匹配,将剩余的出售订单加入sell队列。
  5. return total % mod:返回总订单数量对模数取模的结果。

这个算法使用了贪心策略来处理订单匹配。通过维护两个优先队列,我们可以在O(log n)的时间复杂度内找到合适的匹配订单,从而大大提高了效率。

学习补充:

最大优先队列用于获取并删除队列中具有最大关键字的元素,而最小优先队列则用于获取并删除具有最小关键字的元素

小顶堆是升序,找最小值;

大顶堆是降序,找最大;

最大优先队列和大顶堆 最小优先队列和小顶堆的关系:

最大优先队列,是降序,删除最大值,-------大顶堆是降序,找最大;

最小优先队列是升序,删除最小值;------小顶堆是升序,找最小值;
 

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

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

相关文章

接口测试入门:深入理解接口测试!【电商API接口测试】

很多人会谈论接口测试。到底什么是接口测试&#xff1f;如何进行接口测试&#xff1f;这篇文章会帮到你。 一、前端和后端 在谈论接口测试之前&#xff0c;让我们先明确前端和后端这两个概念。 前端是我们在网页或移动应用程序中看到的页面&#xff0c;它由 HTML 和 CSS 编写…

[重要提示]msvcr120.dll缺失的修复之道,一定要知道!

在使用Windows操作系统的过程中&#xff0c;许多用户可能会遇到与“msvcr120.dll”文件相关的问题。这个DLL文件是Microsoft Visual C Redistributable Package的一部分&#xff0c;当这个文件丢失或损坏时&#xff0c;可能会导致程序无法启动或运行不稳定。如果你正在面对“ms…

为什么越来越多的开发者选择了EasyPlayer播放器?

在当今快速发展的多媒体和数字化时代&#xff0c;视频和音频的播放与处理已成为众多应用的核心功能之一。随着物联网&#xff08;IoT&#xff09;、嵌入式系统、智能硬件以及移动应用的普及&#xff0c;寻找一个高效、灵活且易于集成的多媒体播放解决方案成为了开发者们的重要需…

工业现场网关模块:现代制造业的数据枢纽

在工业4.0和智能制造的推动下&#xff0c;工业现场网关模块成为连接现场设备与上层管理系统的重要桥梁。它们不仅承担着数据采集和传输的任务&#xff0c;还在设备间通讯、系统集成等方面发挥关键作用。本文将详细介绍工业现场网关模块的功能、特点及其在实际应用中的技术实现过…

OpenCV4.8 开发实战系列专栏之 02-图像色彩空间转换

大家好&#xff0c;欢迎大家学习OpenCV4.8 开发实战专栏&#xff0c;长期更新&#xff0c;不断分享源码。 专栏代码全部基于C 与Python双语演示&#xff0c;专栏答疑群 请联系微信 OpenCVXueTang_Asst 本文关键知识点&#xff1a; 色彩空间转换函数- cvtColor COLOR_BGR2GRAY…

这些主流的财务管理软件,你用过哪款?

在当今的商业环境中&#xff0c;财务管理面临着诸多棘手的痛点问题&#xff1a; 数据的准确性与及时性难以保证&#xff0c;手工录入易出错且数据更新常不及时&#xff1b; 预算管理困难重重&#xff0c;编制不合理且执行监控难&#xff1b; 财务风险管控不足&#xff0c;应…

GS-SLAM论文阅读笔记--MM3DGS SLAM

前言 多传感器融合GS-SLAM的另一个IROS2024,不过这篇没有用到激光雷达&#xff0c;而是相机和IMU结合而实现的。今天看一下这篇。 文章目录 前言1.背景介绍2.关键内容2.1 跟踪2.2 深度监督2.3 惯性融合2.4建图2.5 总体流程 3.文章贡献4.个人思考 1.背景介绍 虽然SLAM方法使用…

基于keras 的神经网络股价预测模型

这些年从网上的各位大牛那学到很多&#xff0c;本着开源开放的精神&#xff0c;今天我决定开源我量化交易代码。输入股票代码&#xff0c;和训练的数据时间&#xff0c;自动预测股票未来的走势。。。。。。。。。。。。。。。。。。 #!/usr/bin/env python3 # -*- coding: utf…

物联网系统中隔离式交流转直流AC/DC电源模块方案

01 物联网系统中为什么要使用隔离式AC/DC电源模块 物联网系统中使用隔离式AC/DC电源模块的原因主要基于其在电力转换、系统安全、电磁兼容性以及设备保护等方面的优势。以下是详细分析&#xff1a; 电力转换的高效性 高效转换&#xff1a;隔离式AC/DC电源模块能够将交流电&am…

【中级通信工程师】终端与业务(八):市场营销战略

【零基础3天通关中级通信工程师】 终端与业务(八)&#xff1a;市场营销战略 本文是中级通信工程师考试《终端与业务》科目第八章《市场营销战略》的复习资料和真题汇总。本章的核心内容涵盖了市场营销战略、企业战略的层次与特点、服务的特征、体验式营销的类型等内容。通过本…

专业网站建设必备

专业网站建设不仅仅是简单的页面搭建&#xff0c;更是一项综合性的工程&#xff0c;需要结合行业特性、用户体验和技术创新&#xff0c;打造一个符合企业需求、独具特色的线上空间。 第一印象至关重要 一个企业网站就如同公司的数字名片&#xff0c;第一印象往往决定了用户是否…

C#的属性(Property)应用说明(二)

Property的应用说明补充&#xff1a; 一.自定义逻辑&#xff1a; 可以在 get 和 set 访问器中包含自定义的逻辑。 public class Person {private string name;public string Name{get { return name; }set{if (string.IsNullOrWhiteSpace(value))throw new ArgumentException…

Kubernetes从零到精通(15-安全)

目录 一、Kubernetes API访问控制 1.传输安全(Transport Security) 2.认证(Authentication) 2.1 认证方式 2.2 ServiceAccount和普通用户的区别 2.3 ServiceAccount管理方式 自动ServiceAccount示例 手动ServiceAccount示例 3.鉴权 (Authorization) 3.1鉴权方式 3.2 …

一次阿里云ECS免费试用实践

必坑指南 域名注册了&#xff0c;但是试用版无法完成ICP认证的流程 外网不能访问&#xff0c;推荐使用香港地区–自己就是坑在了杭州 阿里云的网站界面有点太复杂了&#xff0c;经常找不到自己想要的界面 为什么使用ECS ECS 一个在云端的弹性计算服务器。 可以支持对外公网映…

C++进阶:set和map

✨✨所属专栏&#xff1a;C✨✨ ✨✨作者主页&#xff1a;嶔某✨✨ 序列式容器和关联式容器 前⾯我们已经接触过STL中的部分容器如&#xff1a;string、vector、list、deque、array、forward_list等&#xff0c;这些容器统称为序列式容器&#xff0c;因为逻辑结构为线性序列的…

五子棋双人对战项目(1)——WebSocket介绍

目录 一、项目介绍 如何实现实时同步对局&#xff1f; 二、WebSocket 1、什么是WebSocket&#xff1f; 2、WebSocket的报文格式 opcode payload len payload data 3、WebSocket握手过程 4、WebSocket代码的简单编写 三、WebSocket 和 HTTP的关系 1、相同点&#xf…

如何把pdf拆分成一页一页?推荐4个简单方便的拆分方法(内含详细教程)

如何把pdf拆分成一页一页&#xff1f;对于现在的职场来说&#xff0c;想要编辑pdf格式文件还是蛮简单的。PDF文档早就成为了我们日常办公中信息传递与存储的核心载体&#xff0c;因此对于编辑pdf的需求是越来越多了。 关于如何编辑pdf文件&#xff0c;市面上提供了很多方法和软…

七大机器学习常用库一次讲清楚(TensorFlow|Scikit-Learn|NumPy|Keras|PyTorch|LightGBM||NLTK)

机器学习的研究和学习必须使用Python开发库&#xff0c;面对很多个机器学习的Python库或者框架&#xff0c;我们是不是傻傻的分不清&#xff0c;这个那个到底是做什么&#xff0c;什么时候用这个&#xff0c;什么时候用那个&#xff0c;他们各自的优势劣势都有哪些&#xff0c;…

smb文件夹共享设置

UOS统信三种不同场景的文件夹共享,分别是:1、UOS系统间的文件共享;2、Windows7系统访问UOS共享的文件;3、UOS系统访问Windows7共享的文件 文章目录 第二种场景:Windows7系统访问UOS共享的文件步骤一:设置共享密码步骤二:输入共享IP地址步骤三:输入网络密码步骤四:共享…

RabbitMQ高级特性-发送方确认

对于发送方发送消息到RabbitMQ的可靠性机制 引入&#xff1a;在持久化的消息正确存⼊RabbitMQ之后,还需要有⼀段时间(虽然很短,但是不可忽视)才能存⼊磁盘中.RabbitMQ并不会为每条消息都进⾏同步存盘(调⽤内核的fsync⽅法)的处理, 可能仅仅保存到操作系统缓存之中⽽不是物理磁…