LeetCode --- 444 周赛

题目列表

3507. 移除最小数对使数组有序 I
3508. 设计路由器
3509. 最大化交错和为 K 的子序列乘积
3510. 移除最小数对使数组有序 II

一、移除最小数对使数组有序 I & II

在这里插入图片描述

由于数组是给定的,所以本题的操作步骤是固定的,我们只要能快速模拟操作的过程即可
i 、 j i、j ij 为当前进行了操作之后的一对相邻元素下标

  • 如何快速找到 n u m s [ i ] nums[i] nums[i] 左右两边相邻的 n u m s [ l ] 、 n u m s [ r ] nums[l]、nums[r] nums[l]nums[r]

    • 思路一:维护下标的有序集合,当我们进行合并 n u m s [ i ] 、 n u m s [ j ] ( i < j ) nums[i]、nums[j]\ (i<j) nums[i]nums[j] (i<j)时 ,删除 j j j,保留 i i i,当我们要查找 i i i 左右两边的相邻元素时,就去二分查找答案,可以用 s e t set set 维护
    • 思路二:用数组模拟双向链表的增删查改操作,即维护数组 l e f t [ i ] 、 r i g h t [ i ] left[i]、right[i] left[i]right[i],分别记录 i i i 左右两边的元素下标
  • 如何快速的找到和最小的 n u m s [ i ] 、 n u m s [ j ] ? nums[i]、nums[j]? nums[i]nums[j]

    • 可以用最小堆记录 p a i r { n u m s [ i ] + n u m s [ j ] , i } pair\{nums[i]+nums[j],i\} pair{nums[i]+nums[j],i},这里的 i i i 为数对下标中较小的那个,即 i < j i<j i<j
    • 当我们将 n u m s [ i ] 、 n u m s [ j ] nums[i]、nums[j] nums[i]nums[j] 跟新为 n u m s [ i ] + n u m s [ j ] nums[i]+nums[j] nums[i]+nums[j] (记为 s s s)时,不仅需要向堆中添加 { n u m s [ l ] + s , l } 、 { s + n u m s [ r ] , i } \{nums[l]+s,l\}、\{s+nums[r],i\} {nums[l]+s,l}{s+nums[r],i},还需要从堆中删除 { n u m s [ l ] + n u m s [ i ] , l } 、 { n u m s [ i + 1 ] + n u m s [ r ] , j } \{nums[l]+nums[i],l\}、\{nums[i+1]+nums[r],j\} {nums[l]+nums[i],l}{nums[i+1]+nums[r],j},需要用到懒删除的技巧
    • 如果不会懒删除技巧,可以用有序集合 s e t set set 来模拟实现懒删除堆

代码如下

// C++
class Solution {
public:int minimumPairRemoval(vector<int>& nums) {int n = nums.size();vector<int> left(n, -1), right(n + 1, n); // 模拟双向链表priority_queue<pair<long long,int>, vector<pair<long long,int>>, greater<>> pq;int cnt = 0; //  记录 nums[i] > nums[i+1] 的个数,以此来判断数组是否是非递减的// 初始化for(int i = 0; i < n; i++){right[i] = i + 1;if(i + 1 < n) {left[i+1] = i;pq.emplace(nums[i] + nums[i+1], i);cnt += nums[i] > nums[i + 1];}}int step = 0;while(cnt > 0){// 懒删除// right[pq.top().second] >= n 表示当前 pq.top().second 已经被合并后删除// pq.top().first != nums[pq.top().second] + nums[right[pq.top().second]] 表示 nums[right[pq.top().second]] 已经被合并过了while(right[pq.top().second] >= n || pq.top().first != nums[pq.top().second] + nums[right[pq.top().second]]){pq.pop();}auto [s, i] = pq.top(); pq.pop();int l = left[i], j = right[i], r = right[j]; // l,i,j,r 之间的大小关系发生变化// 由于 i、j 要合并,先去掉之前的大小关系if(nums[i] > nums[j]) cnt--;if(l != -1 && nums[l] > nums[i]) cnt--;if(r != n && nums[j] > nums[r]) cnt--;// 加入新的大小关系if(l != -1 && nums[l] > s) cnt++;if(r != n && s > nums[r]) cnt++;// 如果 i 的前面有数字,则将{nums[l]+s,l}加入堆中if(l != -1){pq.emplace(s + nums[l], l);}// 如果 i 的后面有数字,则将{nums[r]+s,r}加入堆中if(r != n){pq.emplace(s + nums[r], i);}// 删除 j 结点,保留 i 结点// 让 i -> r, r -> i// 同时让 j -> n 表示 结点 j 被删除if(j < n) right[i] = right[j], right[j] = n;if(r < n) left[r] = i;nums[i] = s; // 跟新当前合并之后的值step++;}return step;}
};

二、设计路由器

在这里插入图片描述
本题关键理解题意,抽象出我们需要使用的数据结构

  • i n t [ ] f o r w a r d P a c k e t ( ) int[]\ \ forwardPacket() int[]  forwardPacket() 需要先进先出:需要有一个 q u e u e queue queue
  • b o o l a d d P a c k e t ( i n t s o u r c e , i n t d e s t i n a t i o n , i n t t i m e s t a m p ) bool\ \ addPacket(int\ \ source, int\ \ destination, int\ \ timestamp) bool  addPacket(int  source,int  destination,int  timestamp) 要求不能重复插入相同的数据包:需要一个哈希表 u n o r d e r e d _ s e t unordered\_set unordered_set,记录插入过的数据包
  • i n t g e t C o u n t ( i n t d e s t i n a t i o n , i n t s t a r t T i m e , i n t e n d T i m e ) int\ \ getCount(int\ \ destination, int\ \ startTime, int\ \ endTime) int  getCount(int  destination,int  startTime,int  endTime) 获取尚未转发的时间在 [ s t a r t T i m e , e n d T i m e ] [startTime,endTime] [startTime,endTime] 中,且目标为 d e s t i n a t i o n destination destination 的数据包的个数:这里我们可以把 d e s t i n a t i o n destination destination 相同的数据包放在一个数组中,由于数据包是按照时间顺序插入的,我们可以用二分法,获取区间内的数据包个数,即额外维护一个 u n o r d e r e d _ m a p < i n t , v e c t o r < i n t > > unordered\_map<int,vector<int>> unordered_map<int,vector<int>>

代码如下

class Router {unordered_map<int,vector<int>> d_t; // [d, vt]// 这里使用循环数组模拟队列vector<tuple<int,int,int>> v;int l = 0, r = 0;unordered_set<string> st;
public:Router(int memoryLimit) : v(memoryLimit + 1) {}bool addPacket(int s, int d, int t) {string mask = to_string(s) + '|' +  to_string(d) + '|' + to_string(t);if(st.count(mask)) return false;st.insert(mask);if((r + 1)%v.size() == l){ // 队列满auto [ss, dd, tt] = v[l++];l %= v.size();st.erase(to_string(ss) + '|' + to_string(dd) + '|' + to_string(tt));d_t[dd].erase(d_t[dd].begin());}d_t[d].push_back(t);v[r++] = {s, d, t};r %= v.size();return true;}vector<int> forwardPacket() {if(r == l) return {}; // 队列为空auto [s, d, t] = v[l++];l %= v.size();d_t[d].erase(d_t[d].begin());st.erase(to_string(s) + '|' + to_string(d) + '|' + to_string(t));return {s, d, t};}int getCount(int d, int startTime, int endTime) {auto& v = d_t[d];return ranges::upper_bound(v, endTime) - ranges::lower_bound(v, startTime);}
};

三、最大化交错和为 K 的子序列乘积

在这里插入图片描述
本题只需要暴搜即可,因为状态的个数并没有我们想象的那么多

  • 状态定义为 d f s ( i , s , m , o p , e m p t y ) dfs(i,s,m,op,empty) dfs(i,s,m,op,empty)

    • i i i 表示枚举的数字下标
    • s s s 表示交错和
    • m m m 表示子序列的元素乘积
    • o p op op 表示当前元素是取正,还是取负
    • e m p t y empty empty 表示子序列是否为空
  • 有人可能觉得这个状态太多了,肯定会超时
    在这里插入图片描述
    因为 m m m 的取值范围是 [ 1 , 5000 ] [1,5000] [1,5000],但实际上,在当前的数据范围内 m m m 最多只有 394 + 1 394+1 394+1 种可能取值( + 1 +1 +1 表示当子序列中有 0 0 0 时,乘积为 0 0 0),可以通过如下代码进行验证

int init = [](){set<int> st{1};for(int i = 0; i < 150; i++){ // 150 个值auto tmp = st;for(auto x : st){for(int i = 1; i <= 12; i++){ // 每个值有可以取 1~12if(x * i <= 5000){st.insert(x * i);}}}}cout << st.size() << endl;return 0;
}();

代码如下

class Solution {
public:int maxProduct(vector<int>& nums, int k, int limit) {int total = reduce(nums.begin(), nums.end());if (total < abs(k)) { // |k| 太大return -1;}int n = nums.size(), ans = -1;unordered_set<long long> vis;auto dfs = [&](this auto&& dfs, int i, int s, int m, bool op, bool empty) -> void {// 无法让 ans 变得更大// 注意:当 m > limit && ans < 0 时,如果在选择一个0,既能让 m < limt,ans = 0if (ans == limit || m > limit && ans >= 0) { return;}if (i == n) {if (!empty && s == k && m <= limit) { // 合法子序列ans = max(ans, m); // 更新答案的最大值}return;}long long mask = (long long) i << 32 | (s + total) << 15 | m << 2 | op << 1 | empty;if (!vis.insert(mask).second) {return;}// 不选 xdfs(i + 1, s, m, op, empty);// 选 xint x = nums[i];dfs(i + 1, s + (op ? -x : x), min(m * x, limit + 1), !op, false);};dfs(0, 0, 1, false, true);return ans;}
};

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

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

相关文章

限流、降级、熔断、隔离?

在微服务架构中&#xff0c;服务限流、降级、熔断和隔离是保障系统高可用性的核心手段&#xff0c;但它们解决的问题和应用场景不同。以下是它们的区别、解决方案和实际案例的详细说明&#xff1a; 一、服务限流&#xff08;Rate Limiting&#xff09; 定义&#xff1a;通过限…

Day22 -php开发01--留言板+知识点(超全局变量 文件包含 数据库操作 第三方插件)

环境要求&#xff1a;php7.0.9 小皮 navicat phpstorm24.1 知识点&#xff1a;会写&#xff08;留言板 留言板后台&#xff09; 超全局变量 三方插件的使用 文件包含 1、开启小皮并利用navicat新建一个数据库 注意&#xff1a;本地的服务mysql关闭后 才可打开小皮。属…

制造一只电子喵 (qwen2.5:0.5b 微调 LoRA 使用 llama-factory)

AI (神经网络模型) 可以认为是计算机的一种新的 “编程” 方式. 为了充分利用计算机, 只学习传统的编程 (编程语言/代码) 是不够的, 我们还要掌握 AI. 本文以 qwen2.5 和 llama-factory 举栗, 介绍语言模型 (LLM) 的微调 (LoRA SFT). 为了方便上手, 此处选择使用小模型 (qwen2…

LeetCode 解题思路 37(Hot 100)

解题思路&#xff1a; 初始化&#xff1a; 初始化最大举行 max 和栈 stack。左右补零&#xff1a; 考虑柱子递增的边界情况&#xff0c; 初始化填充柱状图 newHeights。遍历处理&#xff1a; 对于每一根遍历到的柱子 newHeights[i]&#xff0c;若柱子高度小于栈口索引&#xf…

HTML — 过渡与动画

HTML过渡与动画是提升网页交互体验的核心技术&#xff0c;主要通过CSS实现动态效果。 过渡 CSS过渡&#xff08;Transition&#xff09;介绍 适用于元素属性变化时的平滑渐变效果&#xff0c;如悬停变色、尺寸调整。通过定义transition-property&#xff08;过渡属性&#xf…

跨站请求是什么?

介绍 跨站请求&#xff08;Cross-Site Request&#xff09;通常是指浏览器在访问一个网站时&#xff0c;向另一个域名的网站发送请求的行为。这个概念在 Web 安全中非常重要&#xff0c;尤其是在涉及到“跨站请求伪造&#xff08;CSRF&#xff09;”和“跨域资源共享&#xff…

Web攻防—SSRF服务端请求伪造Gopher伪协议无回显利用

前言 重学Top10的第二篇&#xff0c;希望各位大佬不要见笑。 SSRF原理 SSRF又叫服务端请求伪造&#xff0c;是一种由服务端发起的恶意请求&#xff0c;SSRF发生在应用程序允许攻击者诱使服务器向任意域或资源发送未经授权的请求时。服务器充当代理&#xff0c;执行攻击者构造…

Hibernate:让对象与数据库无缝对话的全自动ORM框架

一、为什么需要全自动ORM&#xff1f; 在手动编写SQL的时代&#xff0c;开发者需要在Java代码和数据库表之间来回切换&#xff1a; // Java对象 public class User {private Long id;private String name;// getters and setters }// SQL语句 SELECT * FROM user WHERE id ?…

C语言超详细指针知识(一)

通过前面一段时间C语言的学习&#xff0c;我们了解了数组&#xff0c;函数&#xff0c;操作符等的相关知识&#xff0c;今天我们将要开始进行指针的学习&#xff0c;这是C语言中较难掌握的一个部分&#xff0c;一定要认真学习&#xff01;&#xff01;&#xff01; 1.内存与地址…

程序化广告行业(70/89):ABTester系统助力落地页优化实践

程序化广告行业&#xff08;70/89&#xff09;&#xff1a;ABTester系统助力落地页优化实践 在程序化广告领域摸爬滚打多年&#xff0c;深知持续学习和知识共享的重要性。写这篇博客&#xff0c;就是希望能和大家一起深入探索程序化广告行业&#xff0c;共同学习、共同进步。今…

项目管理(高软56)

系列文章目录 项目管理 文章目录 系列文章目录前言一、进度管理二、配置管理三、质量四、风险管理五、真题总结 前言 本节主要讲项目管理知识&#xff0c;这些知识听的有点意思啊。对于技术人想创业&#xff0c;单干的都很有必要听听。 一、进度管理 二、配置管理 三、质量 四…

常见的后缀名

.exe .exe&#xff08;“executable”&#xff08;可执行的&#xff09;&#xff09;是 Windows 操作系统中最常见的可执行文件扩展名。此类文件包含了计算机能够直接运行的机器码指令。当用户双击 .exe 文件时&#xff0c;操作系统会读取其中的指令并执行相应的程序或任务。…

XILINX DDR3专题---(1)IP核时钟框架介绍

1.什么是Reference Clock&#xff0c;这个时钟一定是200MHz吗&#xff1f; 2.为什么APP_DATA是128bit&#xff0c;怎么算出来的&#xff1f; 3.APP &#xff1a;MEM的比值一定是1:4吗&#xff1f; 4.NO BUFFER是什么意思&#xff1f; 5.什么情况下Reference Clock的时钟源可…

Doris 安装部署、实际应用及优化实践:对比 ClickHouse 的深度解析

在实时分析、报表系统以及高并发 OLAP 查询等场景中&#xff0c;列式存储数据库因其卓越的查询性能逐渐成为主流。Doris 和 ClickHouse 是近年来最受欢迎的两款开源 OLAP 引擎&#xff0c;本文将系统介绍 Doris 的安装部署、应用场景及优化实践&#xff0c;并与 ClickHouse 做一…

OracleLinuxR5U5系统重启后启动数据库oracle23ai

1、切换到oracle用户 [rootOracleLinux-R9-U5 ~]# su oracle2、查看oracle是否配置了ORACLE_SID [oracleOracleLinux-R9-U5 root]$ cd ~ [oracleOracleLinux-R9-U5 ~]$ cat .bash_profile3、输出内容如下&#xff1a; [oracleOracleLinux-R9-U5 ~]$ cat .bash_profile # .ba…

【正点原子】STM32MP257 同构多核架构下的 ADC 电压采集与处理应用开发实战

在嵌入式系统中&#xff0c;ADC模拟电压的读取是常见的需求。如何高效、并发、且可控地完成数据采集与处理&#xff1f;本篇文章通过双线程分别绑定在 Linux 系统的不同 CPU 核心上&#xff0c;采集 /sys/bus/iio 接口的 ADC 原始值与缩放系数 scale&#xff0c;并在另一个核上…

电商用户购物行为分析:基于K-Means聚类与分类验证的完整流程

随着电商行业的快速发展,用户行为分析成为企业优化营销策略、提升用户体验的重要手段。通过分析用户的购物行为数据,企业可以挖掘出用户群体的消费特征和行为模式,从而制定更加精准的营销策略。本文将详细介绍一个基于Python实现的电商用户购物行为分析系统,涵盖数据预处理…

AMGCL库的Backends及使用示例

AMGCL库的Backends及使用示例 AMGCL是一个用于解决大型稀疏线性方程组的C库&#xff0c;它提供了多种后端(backends)实现&#xff0c;允许用户根据不同的硬件和性能需求选择合适的计算后端。 AMGCL支持的主要Backends 内置Backends: builtin - 默认的纯C实现block - 支持块状…

Express中间件(Middleware)详解:从零开始掌握(3)

实用中间件模式25例 1. 基础增强模式 请求属性扩展 function extendRequest() {return (req, res, next) > {req.getClientLanguage () > {return req.headers[accept-language]?.split(,)[0] || en;};next();}; } 响应时间头 function responseTime() {return (r…

05--MQTT物联网协议

一、MQTT的概念 MQTT 协议快速入门 2025&#xff1a;基础知识和实用教程 | EMQ 1.MQTT&#xff08;Message Queuing Telemetry Transport&#xff09;是一种轻量级、基于发布-订阅模式的消息传输协议&#xff0c;适用于资源受限的设备和低带宽、高延迟或不稳定的网络环境。它…