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

C语言/数据结构算法题解:环形数组最大连续子段和——单调队列+前缀和O(n)解法

问题描述

小明在玩一个环形数字游戏,游戏规则是:给定一个环形整数数组(即首尾相连的数组),每个元素代表一个位置上的“贡献值”。小明可以自由选择一段连续的位置(由于是环形,选择可以跨越数组首尾),但被选中的位置总数不能超过数组长度的一半。小明想要最大化所选位置的贡献值之和。

需要注意的是,由于是环形数组,当选择跨越首尾时,实际选中的是数组末尾的一部分和开头的一部分组成的连续段。例如数组为 [1,2,3,4,5] 且允许选择3个位置,那么一种可能的选择是 [5,1,2](即索引4,0,1)。

你的任务是帮助小明设计一个算法,在 O(n) 时间复杂度内找到这个最大贡献值。

测试样例

样例1:

输入:nums = [1,2,3,4,5], k = 3输出:12解释:允许选择3个位置,最大和为3+4+5=12(选择索引2,3,4)。其他选择如索引3,4,0(4+5+1=10)或索引4,0,1(5+1+2=8)或索引0,1,2(1+2+3=6)均小于12。

样例2:

输入:nums = [8,2,3,4,5,6], k = 3输出:19解释:最大和为5+6+8=19(选择索引4,5,0)。其他选择如索引0,1,2(8+2+3=13)或索引1,2,3(2+3+4=9)或索引2,3,4(3+4+5=12)或索引3,4,5(4+5+6=15)均小于19。

样例3:

输入:nums = [10,20,30,40], k = 2输出:70解释:最大和为30+40=70(选择索引2,3)。其他选择如索引0,1(10+20=30)或索引1,2(20+30=50)或索引3,0(40+10=50)均小于70。

约束条件

  • 1 <= nums.length <= 10^5
  • -10^4 <= nums[i] <= 10^4
  • 1 <= k <= floor(nums.length / 2) (即k不超过数组长度的一半)
  • 数组是环形的(索引0和n-1相邻)

程序代码

#include <stdio.h>

#include <stdlib.h>

#include <limits.h>

int maxContrib(int* nums, int numsSize, int k) {

int n = numsSize;

// 构建双倍数组

int* doubled = (int*)malloc(2 * n * sizeof(int));

for (int i = 0; i < 2 * n; i++) {

doubled[i] = nums[i % n];

}

// 前缀和

int* prefix = (int*)malloc((2 * n + 1) * sizeof(int));

prefix[0] = 0;

for (int i = 0; i < 2 * n; i++) {

prefix[i + 1] = prefix[i] + doubled[i];

}

// 单调队列:维护前缀和的最小值索引

int* deque = (int*)malloc((2 * n + 1) * sizeof(int));

int head = 0, tail = 0;

int ans = INT_MIN;

// 遍历右端点

for (int i = 1; i <= 2 * n; i++) {

// 移除超出窗口的索引

while (head < tail && deque[head] < i - k) {

head++;

}

// 如果队列不为空,计算以 i-1 结尾的最大和

if (head < tail) {

int sum = prefix[i] - prefix[deque[head]];

if (sum > ans) ans = sum;

}

// 维护单调递增队列

while (head < tail && prefix[deque[tail - 1]] >= prefix[i]) {

tail--;

}

deque[tail++] = i;

}

free(doubled);

free(prefix);

free(deque);

return ans;

}

int main() {

int nums1[] = {1,2,3,4,5};

printf("%d\n", maxContrib(nums1, 5, 3)); // 应输出12

int nums2[] = {8,2,3,4,5,6};

printf("%d\n", maxContrib(nums2, 6, 3)); // 应输出19

int nums3[] = {10,20,30,40};

printf("%d\n", maxContrib(nums3, 4, 2)); // 应输出70

return 0;

}

#include <stdio.h> #include <stdlib.h> #include <limits.h> int maxContrib(int* nums, int numsSize, int k) { int n = numsSize; // 构建双倍数组 int* doubled = (int*)malloc(2 * n * sizeof(int)); for (int i = 0; i < 2 * n; i++) { doubled[i] = nums[i % n]; } // 前缀和 int* prefix = (int*)malloc((2 * n + 1) * sizeof(int)); prefix[0] = 0; for (int i = 0; i < 2 * n; i++) { prefix[i + 1] = prefix[i] + doubled[i]; } // 单调队列:维护前缀和的最小值索引 int* deque = (int*)malloc((2 * n + 1) * sizeof(int)); int head = 0, tail = 0; int ans = INT_MIN; // 遍历右端点 for (int i = 1; i <= 2 * n; i++) { // 移除超出窗口的索引 while (head < tail && deque[head] < i - k) { head++; } // 如果队列不为空,计算以 i-1 结尾的最大和 if (head < tail) { int sum = prefix[i] - prefix[deque[head]]; if (sum > ans) ans = sum; } // 维护单调递增队列 while (head < tail && prefix[deque[tail - 1]] >= prefix[i]) { tail--; } deque[tail++] = i; } free(doubled); free(prefix); free(deque); return ans; } int main() { int nums1[] = {1,2,3,4,5}; printf("%d\n", maxContrib(nums1, 5, 3)); // 应输出12 int nums2[] = {8,2,3,4,5,6}; printf("%d\n", maxContrib(nums2, 6, 3)); // 应输出19 int nums3[] = {10,20,30,40}; printf("%d\n", maxContrib(nums3, 4, 2)); // 应输出70 return 0; }

运行结果

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

相关文章:

  • 微信聊天记录永久保存完整教程:免费工具一键导出,换手机再也不慌
  • RemoteCam核心功能解析:传感器选择、分辨率调节与MJPEG流原理
  • 2026年咸宁短视频代运营正规服务商中网创信怎么选?服务模式、内容体系与避坑要点 - 中国品牌价值观察网
  • 反连平台设计详解:DNSLog + HTTP 回调 + 异步关联,从零实现漏洞扫描 OOB 检测基础设施
  • 如何避免zxpy脚本中的常见陷阱:安全与性能优化指南
  • Search-Engines-Scraper核心功能解密:结果去重、多格式导出与高级过滤技巧
  • 网盘下载慢怎么解决?这款免费开源的网盘直链解析工具一次搞定
  • 珠海斗门区房屋漏水维修靠谱商家推荐(2026新):精准测漏维修 - 超人防水
  • RAGMeUp架构详解:Python后端与React前端的无缝协作
  • 终极显存管理实战:RTX 5090 上 Qwen3-VL-32B INT8 ConvRot 模型部署与性能优化全攻略
  • 2026年8月无锡宜兴屋顶漏水维修哪家好?屋面防水科普指南 - 聪居到家
  • 实测Audio8-ASR-0.1B语音识别效果:WER低至2.7%的技术突破
  • useMergeRefs钩子:优化React组件性能的高级技巧
  • 三步搭建免费工业监控平台:Scada-LTS开源SCADA系统部署实战与避坑指南
  • 2026 年 8 月济南名包出手实测:古驰 Jackie1961 系列回收报价,剖析本地回收常见交易纠纷 - 品牌观测员
  • 终极指南:在iPhone上部署Audio8-ASR-0.1B,200MB内存实现本地语音转写
  • 清新房屋漏水维修靠谱商家推荐(2026新):精准测漏维修 - 超人防水
  • 如何在5分钟内上手u-dma-buf?从编译到设备创建的快速实践
  • DDRM核心功能解析:超分辨率、去模糊与降噪的终极解决方案
  • PyFlow开发者教程:从源码编译到自定义参数调优
  • 超宽温 PT1000 分度表 (-200℃~850℃)
  • GerberTools完整指南:如何快速搞定Gerber文件处理与拼板生产
  • 广州香奈儿二手包包变现科普,年份磨损瑕疵对报价的影响 - 资讯早知道
  • Portrait-Segmentation核心架构解密:Slim-net如何实现1.5MB模型20FPS实时推理
  • 如何利用DeepSeek Harness提升AI开发效率?5个实用技巧与最佳实践
  • Snipe-IT 快速上手:从 Docker 部署到第一台设备入库(约半小时)
  • 漏洞扫描报告生成系统设计:HTML 模板 + JSON 结构化 + 多格式导出,附 5 个安全坑点
  • 如何用 UModel 轻松提取虚幻引擎资源?一份实战上手指南
  • 用工风险管控系统哪家好?科学选购指南 - 汇聚至此
  • 2026年8月哈尔滨南岗区月嫂推荐 哪家照顾新生儿专业指南 - 起跑123