力扣题解2286

大家好,欢迎来到无限大的频道

今天继续给大家带来力扣题解

题目描述(困难):

以组为单位订音乐会的门票
一个音乐会总共有 n 排座位,编号从 0 到 n - 1 ,每一排有 m 个座椅,编号为 0 到 m - 1 。你需要设计一个买票系统,针对以下情况进行座位安排:

  • 同一组的 k 位观众坐在 同一排座位,且座位连续 。
  • k 位观众中 每一位 都有座位坐,但他们 不一定 坐在一起。

由于观众非常挑剔,所以:

  • 只有当一个组里所有成员座位的排数都 小于等于 maxRow ,这个组才能订座位。每一组的 maxRow 可能 不同 。
  • 如果有多排座位可以选择,优先选择 最小 的排数。如果同一排中有多个座位可以坐,优先选择号码 最小 的。

请你实现 BookMyShow 类:

  • BookMyShow(int n, int m) ,初始化对象,n 是排数,m 是每一排的座位数。

  • int[] gather(int k, int maxRow) 返回长度为 2 的数组,表示 k 个成员中 第一个座位的排数和座位编号,这 k 位成员必须坐在同一排座位,且座位连续 。换言之,返回最小可能的 r 和 c 满足第 r 排中 [c, c + k- 1] 的座位都是空的,且 r <= maxRow 。如果 无法 安排座位,返回 [] 。

  • boolean scatter(int k, int maxRow) 如果组里所有 k 个成员 不一定 要坐在一起的前提下,都能在第 0 排到第 maxRow 排之间找到座位,那么请返回 true。这种情况下,每个成员都优先找排数 最小,然后是座位编号最小的座位。如果不能安排所有 k 个成员的座位,请返回 false 。

这道题目中,我们需要设计一个较为复杂的座位安排系统,这里我们使用线段树来维护我们需要的数据 —— 每排座位的最小已坐座位数和已坐座位数之和。我们需要实现两个主要功能:gatherscatter。这两个方法分别按照题目要求,在条件限制下分配座位,并返回相应的结果。

题目解析

  1. gather功能

    • 要求找到一排能容纳k个连续座位的位置。
    • 搜索范围是从第0排到maxRow排。
    • 优先选择排数最小且符合条件的排。
    • 返回该排的行数及第一个座位的编号。
  2. scatter功能

    • 不要求连续,但需要在规定排数内找到足够的k个座位。
    • 搜索范围是从第0排到maxRow排。
    • 在每个排中尽可能填充座位(优先选择排数最小的)。

解题思路

为了高效地管理每排座位的状态,使用了两棵线段树:

  • minTree:维护的是每个区间最小的已用座位数。这帮助我们快速找到满足条件的最小排。
  • sumTree:维护的是每个区间已用座位数的和。这帮助我们快速计算一个区间内的填充情况。

理解minTreesumTree的区别对于掌握线段树的应用非常重要。在这道题中,我们需要管理每排座位的状态来满足gatherscatter需求。让我们逐个解释这两个概念及其用途。

minTree

  • 定义minTree 维护的是一个区间内的最小已用座位数。也就是说,它能够快速查询某一范围(例如某几排)内哪个排的座位使用情况是最少的。

  • 用途:通过查询minTree,我们可以快速找到满足gather条件的最小排(例如,已用座位数小于等于 m - k),这帮助我们高效地找到哪个排还能够再容纳更多的座位,并且确保所选排是可用的、最优的。

例如,当我们要分配k个连续的座位时,我们首先需要找到最小的已用座位数(used)小于等于 m - k 的行。如果某行的已用座位数少于这个值,那么它就是一个合适的选择。

sumTree

  • 定义sumTree 维护的是一个区间内已用座位数的总和。它能够快速计算某一范围(例如多排座位的)的已用座位总数。

  • 用途:在处理scatter时,我们需要知道在某一范围内的总已用座位数。通过查询sumTree,我们可以快速计算这些座位的总数,从而与总座位数进行比较,以判断是否能满足新的需求。

例如,考虑scatter功能时,我们需要查看从第0排到maxRow排的总已用座位数(usedTotal)。我们用这个值来判断在此区间内是否可以再安排k个座位。这也是确保在满足条件下分配座位的必要步骤。

我们主要需要实现以下几个方法:

  1. 修改方法 (modify)

    • 通过更新线段树节点,以反映座位占用的变化。
    • 对一个排添加座位数,更新 minTreesumTree
  2. 查询最小值方法 (queryMinRow)

    • 用来找到满足条件的最小排。
  3. 查询总和方法 (querySum)

    • 用来计算给定区间的已用座位总和。

代码分析

结合思路,我们有以下详细的C语言和C++实现:

C语言实现
typedef struct {int n; // The number of rowsint m; // Seats per rowint *minTree; // Segment tree for minimum occupied seats in a rangelong long *sumTree; // Segment tree for sum of occupied seats in a range
} BookMyShow;BookMyShow *bookMyShowCreate(int n, int m) {BookMyShow *obj = (BookMyShow*)malloc(sizeof(BookMyShow));obj->n = n;obj->m = m;obj->minTree = (int*)malloc(sizeof(int) * (4 * n));obj->sumTree = (long long*)malloc(sizeof(long long) * (4 * n));memset(obj->minTree, 0, sizeof(int) * (4 * n));memset(obj->sumTree, 0, sizeof(long long) * (4 * n));return obj;
}void modify(BookMyShow *obj, int i, int l, int r, int index, int val) {if (l == r) {obj->minTree[i] = val;obj->sumTree[i] = val;return;}int mid = (l + r) / 2;if (index <= mid) {modify(obj, i * 2, l, mid, index, val);} else {modify(obj, i * 2 + 1, mid + 1, r, index, val);}obj->minTree[i] = obj->minTree[i * 2] < obj->minTree[i * 2 + 1] ? obj->minTree[i * 2] : obj->minTree[i * 2 + 1];obj->sumTree[i] = obj->sumTree[i * 2] + obj->sumTree[i * 2 + 1];
}int queryMinRow(BookMyShow *obj, int i, int l, int r, int val) {if (l == r) {if (obj->minTree[i] > val) {return obj->n;}return l;}int mid = (l + r) / 2;if (obj->minTree[i * 2] <= val) {return queryMinRow(obj, i * 2, l, mid, val);} else {return queryMinRow(obj, i * 2 + 1, mid + 1, r, val);}
}long long querySum(BookMyShow *obj, int i, int l, int r, int l2, int r2) {if (r < l2 || l > r2) {return 0;}if (l >= l2 && r <= r2) {return obj->sumTree[i];}int mid = (l + r) / 2;return querySum(obj, i * 2, l, mid, l2, r2) + querySum(obj, i * 2 + 1, mid + 1, r, l2, r2);
}int *bookMyShowGather(BookMyShow *obj, int k, int maxRow, int *retSize) {int i = queryMinRow(obj, 1, 0, obj->n - 1, obj->m - k);if (i > maxRow) {*retSize = 0;return NULL;}int used = querySum(obj, 1, 0, obj->n - 1, i, i);modify(obj, 1, 0, obj->n - 1, i, used + k);int *ret = (int *)malloc(sizeof(int) * 2);ret[0] = i;ret[1] = used;*retSize = 2;return ret;
}bool bookMyShowScatter(BookMyShow *obj, int k, int maxRow) {long long usedTotal = querySum(obj, 1, 0, obj->n - 1, 0, maxRow);if ((maxRow + 1LL) * obj->m - usedTotal < k) {return false;}int i = queryMinRow(obj, 1, 0, obj->n - 1, obj->m - 1);while (k > 0) {int used = querySum(obj, 1, 0, obj->n - 1, i, i);if (obj->m - used >= k) {modify(obj, 1, 0, obj->n - 1, i, used + k);break;}k -= obj->m - used;modify(obj, 1, 0, obj->n - 1, i, obj->m);i++;}return true;
}void bookMyShowFree(BookMyShow *obj) {free(obj->minTree);free(obj->sumTree);free(obj);
}
C++版本实现
class BookMyShow {
private:int n, m;vector<int> minTree;vector<long long> sumTree;void modify(int i, int l, int r, int index, int val) {if (l == r) {minTree[i] = val;sumTree[i] = val;return;}int mid = (l + r) / 2;if (index <= mid) {modify(i * 2, l, mid, index, val);} else {modify(i * 2 + 1, mid + 1, r, index, val);}minTree[i] = min(minTree[i * 2], minTree[i * 2 + 1]);sumTree[i] = sumTree[i * 2] + sumTree[i * 2 + 1];}int queryMinRow(int i, int l, int r, int val) {if (l == r) return minTree[i] > val ? n : l;int mid = (l + r) / 2;if (minTree[i * 2] <= val) {return queryMinRow(i * 2, l, mid, val);} else {return queryMinRow(i * 2 + 1, mid + 1, r, val);}}long long querySum(int i, int l, int r, int l2, int r2) {if (l2 <= l && r <= r2) return sumTree[i];int mid = (l + r) / 2;long long sum = 0;if (mid >= l2) sum += querySum(i * 2, l, mid, l2, r2);if (mid < r2) sum += querySum(i * 2 + 1, mid + 1, r, l2, r2);return sum;}public:BookMyShow(int n, int m): n(n), m(m), minTree(4 * n, 0), sumTree(4 * n, 0) {}vector<int> gather(int k, int maxRow) {int i = queryMinRow(1, 0, n - 1, m - k);if (i > maxRow) return {};int used = querySum(1, 0, n - 1, i, i);modify(1, 0, n - 1, i, used + k);return {i, used};}bool scatter(int k, int maxRow) {long long usedTotal = querySum(1, 0, n - 1, 0, maxRow);if ((long long)(maxRow + 1) * m - usedTotal < k) return false;int i = queryMinRow(1, 0, n - 1, m - 1);while (k > 0) {int used = querySum(1, 0, n - 1, i, i);if (m - used >= k) {modify(1, 0, n - 1, i, used + k);break;}k -= m - used;modify(1, 0, n - 1, i, m);i++;}return true;}
};

代码详解

  1. 创建对象:初始化线段树用于存储可用状态和总状态。

  2. modify方法:在指定位置更新,可在特定行添加已用座位,并更新线段树的相关节点。

  3. gather方法

    • 使用queryMinRow找到满足条件的最小排。
    • 如果找到,得到该排的当前已使用座位数,并在sumTree中进行更新。
  4. scatter方法

    • 利用querySum计算余量并判断是否可行。
    • 然后根据需要分配座位。
  5. 资源释放:在C语言版本中,通过bookMyShowFree方法进行分配的资源释放。

该实现策略利用线段树,在复杂度较低的情况下高效处理不同类型的座位安排请求。通过合理管理每排的状态和快速检索可用排数,我们可以高效满足题目中的要求。

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

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

相关文章

MySQL 性能剖析全攻略

在使用 MySQL 数据库的过程中&#xff0c;性能问题往往是让开发者和管理员头疼的难题。为了有效地解决这些问题&#xff0c;我们需要对 MySQL 进行性能剖析。那么&#xff0c;如何在 MySQL 中进行性能剖析呢&#xff1f;本文将为你详细介绍。 一、为什么要进行性能剖析&#x…

实施自动化测试的五个条件

摘要&#xff1a; 谈到什么是组成一次自动化测试的“恰当实施”经常会关注你需要用的工具&#xff0c;但是那仅仅是等式的一部分。巴斯 迪杰斯特拉详细说明了你需要考虑的其他四件事&#xff0c;他们如何致力于你的自动化测试的成功&#xff0c;以及关联到不能适当关注它们中任…

MNIST手写数字数据集

数据集 官网链接失效&#xff0c;我找到数据集后&#xff0c;上传到码云&#xff0c;并在这里分享。 打开链接&#xff0c;进入如下目录&#xff0c;即可找到如下八个文件&#xff1a; 下面是一些可有可无的介绍。 Mnist数据集介绍 Mnist数据集包含70000张手写数字图片&#x…

5G NR 协议规范表(对应3GPP 协议编号)

文章目录 5G NR 协议规范表&#xff08;对应3GPP 协议编号&#xff09;5G 架构相关协议5G 新空口相关协议无线接入网相关协议终端相关协议 5G NR 协议规范表&#xff08;对应3GPP 协议编号&#xff09; 5G 架构相关协议 5G 新空口相关协议 无线接入网相关协议 终端相关协议

Woocommerce怎么分类显示产品?如何将Shopify的产品导入到Woocommerce?

WooCommerce作为WordPress的一个电子商务插件&#xff0c;功能强大、使用简洁&#xff0c;能够轻松集成到WordPress网站中&#xff0c;为用户提供了一个完整的在线商店解决方案&#xff0c;在国外还是挺受欢迎的。 Woocommerce怎么分类显示产品&#xff1f; 在Woocommerce中&a…

[ComfyUI]Flux:太美了!古风华服与现代DJ演绎。灼灼荷花瑞,亭亭出水中

大家好我是安琪&#xff01;&#xff01;&#xff01; F.1-汉服人像艺术-国风-氛围感 简介 今天介绍一款Flux LORA模型&#xff1a;F.1-汉服人像艺术-国风-氛围感-liangyi&#xff0c;这是一款以古代汉服女性写真为主题的Flux LORA模型。属于人物主体&#xff0c;增加中国传统…

国庆头像制作小程序相关代码

↓↓ 点击下方搜索开始制作您的专属头像 ↓↓ 发现-》搜一搜-》最美易飞证件照制作 国庆头像自定义头像制作、微信头像直接获取制作小程序源码 index.wxml文件代码 // pages/userPhoto/userPhoto.js//获取应用实例const app getApp()import { Router} from ../../utils/ro…

23款奔驰E300立标升级23P智能辅助驾驶案例分享

《23 款奔驰 E300 立标升级 23P 智能辅助驾驶案例》 在汽车科技不断进步的今天&#xff0c;越来越多的车主开始追求更加智能、安全的驾驶体验。今天&#xff0c;我们就为大家带来一款 23 款奔驰 E300 立标升级 23P 智能辅助驾驶的精彩案例。 这辆 23 款奔驰 E300 立标原本就散…

C# Blazor Server 调用海康H5Player播放摄像头画面

目标 调用海康综合安防平台api&#xff0c;通过摄像头的cameraIndexCode调用【获取监控点预览取流URLv2】api&#xff0c;得到websocket 的url&#xff0c;然后在blazor server中使用htplayer.js播放摄像头实时画面。 步骤 根据摄像头名字&#xff0c;调用【查询监控点列表v2…

Python编码系列—Python命令模式:将请求封装为对象

&#x1f31f;&#x1f31f; 欢迎来到我的技术小筑&#xff0c;一个专为技术探索者打造的交流空间。在这里&#xff0c;我们不仅分享代码的智慧&#xff0c;还探讨技术的深度与广度。无论您是资深开发者还是技术新手&#xff0c;这里都有一片属于您的天空。让我们在知识的海洋中…

CentOS8.5.2111(3)实验之DHCP服务器架设

一、实验目标 1&#xff0e;掌握DHCP服务器的主配置文件各项申明参数及操作及其含义 2. 具备DHCP 服务器、中继服务器的配置能力 3. 具备测试客户端正常获取服务器分配地址的能力 4. 具备DHCP服务器故障排除能力 二、实训原理/流程 &#xff08;一&#xff09;项目背景 …

python爬虫案例——抓取链家租房信息(8)

文章目录 1、任务目标2、分析网页3、编写代码1、任务目标 目标站点:链家租房版块(https://bj.lianjia.com/zufang/) 要求:抓取该链接下前5页所有的租房信息,包括:标题、详情信息、详情链接、价格 如: 2、分析网页 用浏览器打开链接,按F12或右键检查,进入开发者模式;因…

首屏优化之:SSR(服务端渲染)

引言 今天我们来聊一下首屏优化之SSR-服务端渲染&#xff08;Server-Side Rendering&#xff09;。 可能很多朋友并不了解什么是 SSR&#xff0c;包括在工作中写的网站是什么类型的也不太清楚&#xff0c;是 CSR 还是 SSR&#xff1f;作者在阅读过大量的文章之后&#xff0c;…

一文上手SpringSecurity【二】

书接上回,我们直接引入了spring security的依赖,之后啥也没有干,在访问接口的时候, 就需要认证之后才能访问了 ,咱们没有主动干啥,那肯定有人帮助我们干啥了,这一切都利益出spring boot自动装配机制,下面咱们就看看spring security的自动装配,帮助我们干啥了. 一、Spring Secur…

如何查看上网记录及上网时间?5种按步操作的方法分享!【小白也能学会!】

“知己知彼&#xff0c;百战不殆”&#xff0c;在数字时代&#xff0c;了解自己的上网行为和时长&#xff0c;不仅能帮助我们更好地管理时间&#xff0c;还能提升工作效率和生活质量。 今天&#xff0c;我们就来分享五种简单易懂的方法&#xff0c;即便是网络小白也能轻松学会…

某系统超级管理员密码重置通用型

故事的起因是意外发现某站点系统存在接口泄露&#xff0c;并且此接口可直接实现超级管理员密码重置&#xff0c;查ico找到用这个系统的站点&#xff0c;发现均存在此漏洞 首先打开系统站点&#xff0c;F12或者鼠标右键检查&#xff0c;然后刷新页面&#xff0c;在网络这里找到…

ECCV`24 | 高保真目标修复新SOTA!复旦智象开源CAT-Diffusion,语义视觉双一致

文章链接&#xff1a;https://arxiv.org/pdf/2409.08260 Github链接&#xff1a;https://github.com/Nnn-s/CATdiffusion 总结速览 解决的问题: 单一U-Net在所有去噪步骤中对齐文本提示和视觉对象不足以生成期望的对象。 扩散模型的复杂采样空间中无法保证对对象生成的可控性…

物流货运托运发货单二联三联打印软件定制 佳易王物流单管理系统操作教程

一、前言 物流货运托运发货单二联三联打印软件定制 佳易王物流单管理系统操作教程 1、软件为绿色免安装版&#xff0c;解压即可使用&#xff0c;已经内置数据库&#xff0c;不需再安装。 2、软件下载可以到本文章最后点击官网卡片下。 二、软件程序教程 1、如图&#xff0c;…

Html 转为 MarkDown

在 RAG 中,通常需要将 HTML 转为 Markdown,有很多第三方 API 都支持 HTML 的转换,本文使用一个代码文档的例子 https://www.joinquant.com/help/api/help#name:Stock,将聚宽 API 转为 Markdown。本文通过两种方式进行实现,使用收费和开源的解决方案。聚宽 API 格式转为 Ma…

crypto-js解密报错malformed utf-8 data

在进行加解密处理时出现这个问题。 但是当在一个完整程序运行环境内加密字符串&#xff0c;解密字符串是没问题的。 当把加密的字符存储到txt文件&#xff0c;在读取解密时出现错误无法解密。 最后&#xff0c;使用res.replace(/\s/g,‘’)正则过滤掉txt文件内的空格就成功了。…