当前位置: 首页 > news >正文

Kimi LeetCode 3480. 删除一个冲突对后最大子数组数目 C语言实现

以下是 LeetCode 3480 删除一个冲突对后最大子数组数目 的 C 语言实现。

思路

核心思路是枚举子数组右端点,维护当前最严格和次严格的冲突限制:

1. 预处理:将每个冲突对 `(a, b)` 按较大值(即右端点)分组。对于子数组右端点 `right`,所有较大值为 `right` 的冲突对都会在此刻生效。
2. 维护两个关键变量:
- `maxLeft`:所有已生效冲突对中最大的左端点。以 `right` 结尾的合法子数组,其左端点必须 `> maxLeft`,因此贡献 `right - maxLeft` 个合法子数组。
- `secondMaxLeft`:次大的左端点。如果删除 `maxLeft` 对应的那个冲突对,限制会放宽到 `secondMaxLeft`,此时能多获得 `maxLeft - secondMaxLeft` 个子数组。
3. 记录收益:用 `gains[left]` 数组记录“如果删除那个使 `maxLeft` 达到 `left` 的冲突对”所能获得的总额外子数组数。
4. 最终答案:`合法子数组总数 + max(gains)`

时间复杂度 O(n + m),空间复杂度 O(n + m)。

C 代码

```c
#include <stdlib.h>

long long maxSubarrays(int n, int** conflictingPairs, int conflictingPairsSize, int* conflictingPairsColSize) {
// ---------- 1. 按冲突对的较大值(右端点)分组 ----------
int* cnt = (int*)calloc(n + 1, sizeof(int));
for (int i = 0; i < conflictingPairsSize; i++) {
int a = conflictingPairs[i][0];
int b = conflictingPairs[i][1];
int mx = a > b ? a : b; // 较大值作为右端点
cnt[mx]++;
}

// 分配二维数组 conflicts[right] 存储所有左端点
int** conflicts = (int**)malloc((n + 1) * sizeof(int*));
for (int i = 0; i <= n; i++) {
conflicts[i] = (int*)malloc(cnt[i] * sizeof(int));
}

int* idx = (int*)calloc(n + 1, sizeof(int));
for (int i = 0; i < conflictingPairsSize; i++) {
int a = conflictingPairs[i][0];
int b = conflictingPairs[i][1];
int mx = a > b ? a : b;
int mn = a < b ? a : b; // 较小值作为左端点
conflicts[mx][idx[mx]++] = mn;
}

// ---------- 2. 枚举右端点,计算合法子数组和删除收益 ----------
long long validSubarrays = 0;
int maxLeft = 0; // 当前最严格的冲突左端点
int secondMaxLeft = 0; // 次严格的冲突左端点
long long* gains = (long long*)calloc(n + 1, sizeof(long long));

for (int right = 1; right <= n; right++) {
// 加入所有以 right 为较大值的冲突对
for (int j = 0; j < cnt[right]; j++) {
int left = conflicts[right][j];
if (left > maxLeft) {
secondMaxLeft = maxLeft;
maxLeft = left;
} else if (left > secondMaxLeft) {
secondMaxLeft = left;
}
}

// 以 right 结尾的合法子数组数量:左端点必须 > maxLeft
validSubarrays += (long long)(right - maxLeft);

// 若删除当前 maxLeft 对应的冲突对,能多获得的子数组数
gains[maxLeft] += (long long)(maxLeft - secondMaxLeft);
}

// ---------- 3. 找到删除一个冲突对后的最大收益 ----------
long long maxGain = 0;
for (int i = 0; i <= n; i++) {
if (gains[i] > maxGain) {
maxGain = gains[i];
}
}

// 释放内存(LeetCode 不强制要求,但良好习惯)
free(cnt);
free(idx);
for (int i = 0; i <= n; i++) {
free(conflicts[i]);
}
free(conflicts);
free(gains);

return validSubarrays + maxGain;
}
```

复杂度分析

指标 复杂度
时间 O(n + m),其中 `m = conflictingPairsSize`
空间 O(n + m)

该解法通过一次线性扫描完成,无需排序,效率最优。

http://www.jsqmd.com/news/1135048/

相关文章:

  • Windows 11开始菜单失效:专业级修复方案与ExplorerPatcher深度技术解析
  • BigCLAM 算法 Python 实现:从 AGM 模型到 4 社区划分的 100 步梯度下降
  • 38元/年搭个云服务器:我在阿里云云小站薅到的第一个羊毛(附完整教程)
  • 【第五十二周】结果分析
  • Electron 鸿蒙 PC 上做本地搜索,Fuse.js 比 SQLite 快 6 倍——但我愣是选了最慢的方案
  • Kimi LeetCode 3485. 删除元素后 K 个字符串的最长公共前缀 Java实现
  • SV基础之连接设计和测试平台
  • OpenClaw专栏第三篇:环境搭建前的准备工作清单(保姆级避坑指南)
  • YOLO26 TensorBoard集成:可视化训练过程的完整配置与高级用法
  • Wave-ViT: Unifying Wavelet and Transformersfor Visual Representation Learning ——ECCV
  • 解决UE4SS在Palworld游戏中的崩溃问题:GUI控制台兼容性深度解析
  • 西天取经四人组(Liunx小测试)
  • 在上一篇文章NHibernate实践总结(一)中,主要罗列了自己的一部分实践总结,其中包括:
  • C++ Primer Plus 重读精讲 _ 名称空间与代码组织
  • Windows 7用户必备:让Blender 3.x+在旧系统上焕发新生的终极方案
  • 实验一:IP 地址规划、静态路由及 DHCP 配置
  • EldenRingSaveCopier:三步完成艾尔登法环存档迁移的终极解决方案
  • 计算机组成原理4
  • 如何下载沪深股票市场的行情数据,包括委托、成交、订单薄、沪深股票、etf、可转债、指数五档订单薄数据,买一到买五、卖一到卖五历史行情数据笔记
  • Claude Code 是什么
  • 5个常见泰拉瑞亚创作难题,TEdit地图编辑器如何帮你轻松解决?
  • 好久不在这里写文章了。先祝各位六一儿童节快乐!
  • 第一章 为什么90%的Camera项目,都死在第一步?
  • 基于YOLOv8的铁路障碍物检测:从数据准备到边缘部署全流程实践
  • MySQL 视图详解
  • 吾爱大佬最新出品,牛批Plus!
  • Jenkins与SonarQube集成实战:5步构建代码质量自动化分析体系
  • MediaPipe BlazePose 33关键点实战:Python+OpenCV 实现深蹲计数与角度可视化
  • Java程序设计(第3版)第四章——类加载
  • 计算机毕业设计之基于JSP绿色旅游生态园管理系统