c++ 解决区间最大数和矩阵最大面积

给定一个实数序列,设计一个最有效的算法,找到一个总和数最大的区间等于某个事先给定的数字。

我们可以使用前缀和和哈希表来设计一个高效的算法。这个算法的时间复杂度是 O(n),空间复杂度也是 O(n)。

#include <vector>
#include <unordered_map>
#include <iostream>std::pair<int, int> findMaxLengthSubarrayWithSum(const std::vector<double>& arr, double targetSum) {std::unordered_map<double, int> sumIndex; // 用于存储前缀和及其索引double currentSum = 0; // 当前的前缀和int maxLength = 0; // 最长子数组的长度int endIndex = -1; // 最长子数组的结束索引sumIndex[0] = -1; // 初始化前缀和为0的索引为-1for (int i = 0; i < arr.size(); ++i) {currentSum += arr[i]; // 计算当前前缀和double complement = currentSum - targetSum; // 计算需要寻找的互补和if (sumIndex.find(complement) != sumIndex.end()) { // 如果找到了互补和int length = i - sumIndex[complement]; // 计算子数组长度if (length > maxLength) { // 如果这个子数组更长maxLength = length; // 更新最大长度endIndex = i; // 更新结束索引}}if (sumIndex.find(currentSum) == sumIndex.end()) { // 如果这个前缀和之前没出现过sumIndex[currentSum] = i; // 记录这个前缀和的索引}}if (endIndex != -1) { // 如果找到了符合条件的子数组return {endIndex - maxLength + 1, endIndex}; // 返回起始和结束索引} else {return {-1, -1}; // 如果没找到,返回{-1, -1}}
}int main() {std::vector<double> arr = {1.0, 4.0, 20.0, 3.0, 10.0, 5.0}; // 示例数组double targetSum = 33.0; // 目标和auto result = findMaxLengthSubarrayWithSum(arr, targetSum); // 调用函数查找子数组if (result.first != -1) { // 如果找到了符合条件的子数组std::cout << "找到了和为 " << targetSum << " 的最长子数组,索引范围: [" << result.first << ", " << result.second << "]" << std::endl;} else { // 如果没有找到符合条件的子数组std::cout << "没有找到和为 " << targetSum << " 的子数组" << std::endl;}return 0;
}

这个算法的工作原理如下:

  1. 我们使用一个哈希表 sumIndex 来存储每个前缀和及其对应的索引。
  2. 我们遍历数组,不断累加当前的和 currentSum
  3. 对于每个位置,我们计算 complement = currentSum - targetSum。如果这个 complement 存在于我们的哈希表中,那么说明我们找到了一个和为 targetSum 的子数组。
  4. 我们记录找到的最长的子数组。
  5. 如果当前的 currentSum 还没有在哈希表中,我们就将它加入哈希表。

这个算法的优点是:

  • 时间复杂度为 O(n),因为我们只需要遍历一次数组。
  • 空间复杂度为 O(n),用于存储哈希表。
  • 它可以处理包含正数、负数和零的数组。
  • 它可以找到最长的符合条件的子数组。

这个算法比简单的滑动窗口方法更有效,因为它可以处理包含负数的情况,并且可以在一次遍历中找到最长的符合条件的子数组。

第二个问题,在一个二维矩阵中,寻找一个矩阵的区域,使其中的数字之和达到最大值,著名的"最大子矩阵和"问题。我们可以使用Kadane算法的二维扩展来解决这个问题。以下是C++实现,并附有中文注释:

#include <vector>
#include <climits>
#include <iostream>struct SubMatrix {int top, left, bottom, right, sum;
};SubMatrix findMaxSumSubMatrix(const std::vector<std::vector<int>>& matrix) {int rows = matrix.size();if (rows == 0) return {0, 0, 0, 0, 0};int cols = matrix[0].size();if (cols == 0) return {0, 0, 0, 0, 0};SubMatrix result = {0, 0, 0, 0, INT_MIN}; // 存储最终结果std::vector<int> temp(rows, 0); // 临时数组,用于存储列的和// 枚举所有可能的左右列边界for (int left = 0; left < cols; ++left) {std::fill(temp.begin(), temp.end(), 0); // 重置临时数组for (int right = left; right < cols; ++right) {// 将当前列加到临时数组中for (int i = 0; i < rows; ++i) {temp[i] += matrix[i][right];}// 在临时数组上应用一维Kadane算法int currentSum = 0;int maxSum = INT_MIN;int tempTop = 0, top = 0, bottom = 0;for (int i = 0; i < rows; ++i) {currentSum += temp[i];if (currentSum > maxSum) {maxSum = currentSum;top = tempTop;bottom = i;}if (currentSum < 0) {currentSum = 0;tempTop = i + 1;}}// 更新全局最大值if (maxSum > result.sum) {result = {top, left, bottom, right, maxSum};}}}return result;
}int main() {std::vector<std::vector<int>> matrix = {{1, 2, -1, -4, -20},{-8, -3, 4, 2, 1},{3, 8, 10, 1, 3},{-4, -1, 1, 7, -6}};SubMatrix result = findMaxSumSubMatrix(matrix);std::cout << "最大子矩阵和为: " << result.sum << std::endl;std::cout << "子矩阵位置: (" << result.top << "," << result.left << ") 到 ("<< result.bottom << "," << result.right << ")" << std::endl;return 0;
}

这个算法的工作原理如下:

  1. 我们枚举矩阵的所有可能的左右列边界。
  2. 对于每一对左右边界,我们计算这些列之间所有元素的和,存储在一个临时数组中。
  3. 在这个临时数组上,我们应用一维的Kadane算法来找到最大子数组和,这个子数组对应于我们要找的子矩阵的上下边界。
  4. 我们跟踪全局最大和及其对应的子矩阵位置。
  5. 最后返回具有最大和的子矩阵。

这个算法的时间复杂度是O(n^3),其中n是矩阵的边长(假设矩阵是方阵)。虽然这不是最优的解法,但它是较为直观且易于实现的方法。

对于更大的矩阵,存在更高效的算法,如使用二维线段树或者二维树状数组的方法,它们可以将时间复杂度降低到O(n^2 log n)或O(n^2)。但这些方法的实现会更加复杂。

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

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

相关文章

python查找支撑数 青少年编程电子学会python编程等级考试三级真题解析2022年3月

目录 python查找支撑数 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序代码 四、程序说明 五、运行结果 六、考点分析 七、 推荐资料 1、蓝桥杯比赛 2、考级资料 3、其它资料 python查找支撑数 2022年3月 python编程等级考试级编程题 一、题目要求…

RabbitMQ 的经典问题

文章目录 前言一、防止消息丢失1.1 ConfirmCallback/ReturnCallback1.2 持久化1.3 消费者确认消息 二、防止重复消费三、处理消息堆积四、有序消费消息五、实现延时队列六、小结推荐阅读 前言 当设计和运维消息队列系统时&#xff0c;如 RabbitMQ&#xff0c;有几个关键问题需…

第100+13步 ChatGPT学习:R实现决策树分类

基于R 4.2.2版本演示 一、写在前面 有不少大佬问做机器学习分类能不能用R语言&#xff0c;不想学Python咯。 答曰&#xff1a;可&#xff01;用GPT或者Kimi转一下就得了呗。 加上最近也没啥内容写了&#xff0c;就帮各位搬运一下吧。 二、R代码实现决策树分类 &#xff08;…

【漏洞复现】宏景HCM人力资源信息管理系统——任意文件读取漏洞

声明&#xff1a;本文档或演示材料仅供教育和教学目的使用&#xff0c;任何个人或组织使用本文档中的信息进行非法活动&#xff0c;均与本文档的作者或发布者无关。 文章目录 漏洞描述漏洞复现测试工具 漏洞描述 宏景HCM人力资源信息管理系统是一款全面覆盖人力资源管理各模块…

docker pull 镜像的时候遇到Pulling fs layer问题

最近遇到一个很奇怪的问题,docker pull 镜像的时候,总是出现Pulling fs layer问题,导致镜像拉取不成功,以前是安装好docker,正常拉取镜像都是没什么问题的,在这里记录一下这个问题的解决方法,当然,可能并不通用。 1、进入阿里云容器服务 地址:https://cr.console.aliy…

Spring Boot中的热部署配置

Spring Boot中的热部署配置 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天我们将探讨如何在Spring Boot项目中实现热部署配置&#xff0c;提升开发效率和项…

C++实现Qt的信号+槽功能

在 Visual Studio (VS) 上使用 C 实现类似 Qt 的信号和槽机制是完全可能的&#xff0c;但 Qt 的信号和槽系统是基于其特定的元对象系统&#xff08;Meta-Object System, MOC&#xff09;的&#xff0c;这需要一些特定的预处理器和代码生成步骤。 如果你不想使用 Qt&#xff0c;…

vue路由传参和react 路由传参

路由跳转的方式 1、声明式导航 <router-link to"导航的地址"> 2、编程式导航 编程式导航有三种方法来进行导航 router.push router.replace router.go params传参和query传参 1、 params 传参(不在URL中显示参数) 在父路由跳转到子路由时&#xff0c;也可…

【Django】网上蛋糕项目商城-热销和新品

概念 本文将完成实现项目的热销和新品两个分类的商品列表进行分页展示。 热销和新品功能实现步骤 在head.html头部页面中点击这两个超链接向服务器发送请求。 在urls.py文件中定义该请求地址 path(goodsrecommend_list/,views.goodsrecommend_list) 在views.py文件中定义g…

JDBC中的批处理是什么?如何使用?

JDBC中的批处理是指将多个关联的SQL语句组合成一个批处理&#xff0c;并将它们作为一个调用提交给数据库。这种方法可以减少通信的资源消耗&#xff0c;从而提高性能。以下是关于JDBC批处理的具体使用和步骤&#xff1a; 1. JDBC批处理的基本概念 批处理定义&#xff1a;将多…

英飞凌TC3xx之一起认识GTM(十五)GTM常见配置问题总结

英飞凌TC3xx之一起认识GTM(十五)GTM常见配置问题总结 1 关于TGC/AGC的配置注意事项2 关于HOST_TRIG的使用3 关于SOMC模式中MCS与ARU的合并使用配置4 深入理解SOMP模式中RST_CCU0的配置5 关于CCUx中断的使用6 TIM如何捕获ATOM的输出7 总结前面几篇关键文章信息链接汇总如下: …

AV Foundation学习笔记二 - 播放器

ASSets AVFoundation框架的最核心的类是AVAsset&#xff0c;该类是整个AVFoundation框架设计的中心。AVAsset是一个抽象的&#xff08;意味着你不能调用AVAsset的alloc或者new方法来创建一个AVAsset实例对象&#xff0c;而是通过该类的静态方法来创建实例对象&#xff09;、不…

DevOps CMDB平台整合Jira工单

背景 在DevOps CMDB平台建设的过程中&#xff0c;我们可以很容易的将业务应用所涉及的云资源&#xff08;WAF、K8S、虚拟机等&#xff09;、CICD工具链&#xff08;Jenkins、ArgoCD&#xff09;、监控、日志等一次性的维护到CMDB平台&#xff0c;但随着时间的推移&#xff0c;…

Stirling PDF 部署 - 强大的PDF Web在线编辑工具箱

简介 这是一个强大的、可本地托管的、基于 Web 的 PDF 操作工具&#xff0c;可使用 Docker部署。它使您能够对 PDF 文件执行各种操作&#xff0c;包括拆分、合并、转换、重组、添加图像、旋转、压缩等。这个本地托管的 Web 应用程序已经发展到包含一套全面的功能&#xff0c;可…

PHP爬虫类的并发与多线程处理技巧

PHP爬虫类的并发与多线程处理技巧 引言&#xff1a; 随着互联网的快速发展&#xff0c;大量的数据信息存储在各种网站上&#xff0c;获取这些数据已经成为很多业务场景下的需求。而爬虫作为一种自动化获取网络信息的工具&#xff0c;被广泛应用于数据采集、搜索引擎、舆情分析…

关于组织赴俄罗斯(莫斯科)第 28 届国际汽车零部件、汽车维修设备和商品展览会商务考察的通知

关于组织赴俄罗斯&#xff08;莫斯科&#xff09; 第 28 届国际汽车零部件、汽车维修设备和商品展览会商务考察的通知 展会名称&#xff1a;俄罗斯&#xff08;莫斯科&#xff09;第 28 届国际汽车零部件、汽车零部件、汽车维修设备和商品展览会 时间&#xff1a;2024 年 8 月…

Python | Leetcode Python题解之第204题计数质数

题目&#xff1a; 题解&#xff1a; MX5000000 is_prime [1] * MX is_prime[0]is_prime[1]0 for i in range(2, MX):if is_prime[i]:for j in range(i * i, MX, i):#循环每次增加iis_prime[j] 0 class Solution:def countPrimes(self, n: int) -> int:return sum(is_prim…

【MongoDB】分布式数据库入门级学习

SueWakeup 个人主页&#xff1a;SueWakeup 系列专栏&#xff1a;为祖国的科技进步添砖Java 个性签名&#xff1a;保留赤子之心也许是种幸运吧 本文封面由 凯楠&#x1f4f8;友情提供 凯楠&#x1f4f8; - 不夜长安 目录 MongoDB 相关 数据库排行榜单 MongoDB 中文官网 菜鸟…

如何把mkv转成mp4?介绍一下将mkv转成MP4的几种方法

如何把mkv转成mp4&#xff1f;如果你有一个MKV格式的视频文件&#xff0c;但是需要将其转换为MP4格式以便更广泛地在各种设备和平台上播放和共享&#xff0c;你可以通过进行简单的文件格式转换来实现。转换MKV到MP4格式可以提供更好的兼容性&#xff0c;并确保你的视频文件能够…

在预训练语言模型主流架构

文章目录 编码器-解码器架构因果解码器架构前缀解码器架构在预训练语言模型时代,自然语言处理领域广泛采用了预训练 + 微调的范式,并诞生了以 BERT 为代表的编码器(Encoder-only)架构、以 GPT 为代表的解码器(Decoder-only)架构和以 T5 为代表的编码器-解码器(Encoder-d…