最大连续子数组

最大连续子数组(Maximum Subarray)问题是一个经典的算法问题,其目标是在给定的整数数组中找到一个连续的子数组,使得该子数组的元素之和最大。这个问题有多种解决方法,其中包括暴力解法、分治法和动态规划等。

下面是一个讲解最大连续子数组问题的常见解决方法:

  1. 暴力解法: 暴力解法是最简单的方法,它通过两层嵌套循环遍历所有可能的子数组,计算它们的和,并找到和最大的子数组。这个方法的时间复杂度是O(n^2),其中n是数组的长度。尽管它不是最高效的方法,但它是一个朴素而容易理解的解决方案。

  2. 动态规划: 动态规划是解决最大连续子数组问题的高效方法之一。在这种方法中,我们维护一个动态规划数组dp,其中dp[i]表示以第i个元素结尾的最大子数组和。动态规划的关键是通过递推关系来计算dp[i],这个关系通常是 dp[i] = max(dp[i-1] + nums[i], nums[i])。最终,最大子数组和就是dp数组中的最大值。这个方法的时间复杂度是O(n),其中n是数组的长度。

  3. 分治法: 分治法是另一种解决最大连续子数组问题的方法。它将数组分成三个部分:左子数组、右子数组和跨越中间的子数组。然后,递归地求解左子数组和右子数组的最大子数组和,以及跨越中间的最大子数组和。最后,将这三者中的最大值作为最终的结果。这个方法的时间复杂度是O(n*log(n)),其中n是数组的长度。

  4. Kadane算法: Kadane算法是一种高效的动态规划方法,用于解决最大连续子数组问题。它维护两个变量,cur表示当前子数组的和,maxv表示最大子数组和。在遍历数组的过程中,它不断更新curmaxv,并且当cur小于0时,将cur重置为0。最终,maxv就是最大子数组和。这个方法的时间复杂度是O(n),其中n是数组的长度。

我们来看看代码
 

int fun04(int* p, int left, int right);
void fun()
{int i=0, j=0, k=0;int len;int maxv;int v[] = { 1,-3,6,8,0,-7,8 };len = 7; maxv = v[0];for (int i = 0; i < len; i++){for (j = i; j < len; j++){if (j == i){maxv = max(maxv, v[j]);}else {v[i] += v[j];maxv = max(maxv, v[i]);}}}cout << maxv << endl;
}
void fun01()
{int v[] = { 1,-3,6,8,0,-7,8 };int dp[7];dp[0] = v[0];int maxv = dp[0];for (int i = 1; i < 7; i++){dp[i] = max(dp[i - 1] + v[i], v[i]);maxv = max(maxv, dp[i]);}cout << maxv << endl;
}void fun02() {int v[] = { -2,-1 };int maxv = v[0];int cur = 0; for (int i = 0; i < 2; i++) {cur += v[i];maxv = max(maxv, cur);if (cur >= 0) {maxv = max(maxv, cur);}else {cur = 0;}}cout << maxv << endl;
}void fun03() {int v[] = { 1,-3,6,8,0,-7,8 };cout << fun04(v, 0, 6);
}
int fun04(int* p, int left, int right) {if (left == right) {return p[left];}int mid = (left + right) >> 1;int maxleft = fun04(p, left, mid);int maxright = fun04(p, mid + 1, right);int tmpleft = p[mid - 1];int tmp = tmpleft;for (int i = mid - 2; i >= 0; i--) {tmp += p[i];tmpleft = max(tmp, tmpleft);}int tmpright = p[mid + 1];tmp = tmpright;for (int i = mid + 2; i < right; i++){tmp += p[i];tmpright = max(tmp, tmpright);}int midmax = p[mid] + (tmpleft > 0 ? tmpleft : 0) + (tmpright > 0 ? tmpright : 0);return max(maxleft, maxright > midmax ? maxright : midmax);
}

上面的代码演示了几种不同的方法来找到数组中的最大子数组和(最大子序列和问题),并进行了简要的分析。

  1. fun() 方法使用了嵌套的两个 for 循环来遍历所有可能的子数组和,同时维护最大值。这是一种朴素的暴力解法,时间复杂度为O(n^2),其中n是数组的长度。

  2. fun01() 方法使用了动态规划的思想,维护一个dp数组,其中dp[i]表示以第i个元素结尾的最大子数组和。在遍历数组的过程中,根据前一个元素的最大子数组和来计算当前元素的最大子数组和,从而避免了重复计算。这种方法的时间复杂度为O(n),其中n是数组的长度。

  3. fun02() 方法是一种更简单的方法,它遍历一次数组,同时维护当前子数组的和cur和最大子数组和maxv。当cur小于0时,表示当前子数组和不再对最大子数组和有贡献,需要将cur重置为0。这种方法也是O(n)时间复杂度。

  4. fun03() 方法是一个递归的分治方法,其中 fun04() 函数采用分治思想来寻找最大子数组和。它将数组分为左右两部分,然后分别计算左部分、右部分以及跨越中间的最大子数组和,然后取三者中的最大值作为最终的结果。这个方法的时间复杂度也是O(n*log(n)),因为它每次将数组分成两半,需要进行递归处理。

总的来说,动态规划方法(fun01()fun02())是解决最大子数组和问题的较优解,具有O(n)的时间复杂度,而分治方法(fun03())也是一个有效的算法,但在实际情况中可能不如动态规划方法高效。朴素的暴力解法(fun())具有O(n^2)的时间复杂度,不适用于大规模数据。选择合适的算法取决于实际问题和性能要求。

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

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

相关文章

数字化转型:云表低代码开发助力制造业腾飞

数字化转型已成为制造业不可避免的趋势。为了应对市场快速变化、提高运营效率以及降低成本&#xff0c;制造业企业积极追求更加智能化、敏捷的生产方式。在这个转型过程中&#xff0c;低代码技术作为一种强大的工具&#xff0c;正逐渐崭露头角&#xff0c;有望加速制造业的数字…

6个机器学习可解释性框架

1、SHAP SHapley Additive explanation (SHAP)是一种解释任何机器学习模型输出的博弈论方法。它利用博弈论中的经典Shapley值及其相关扩展将最优信贷分配与局部解释联系起来. 举例&#xff1a;基于随机森林模型的心脏病患者预测分类 数据集中每个特征对模型预测的贡献由Shap…

Mac下flutter工程配置Gitlab cicd打包(暂时仅限android侧)

写的太粗糙&#xff0c;可能不太适合完全不懂的同学&#xff0c;但是实在没时间&#xff0c;而且也不太会写&#xff0c;权当做一个记录吧&#xff0c;对了还没有搞docker这些&#xff0c;还在持续学习中 1.GitLab Runner&#xff08;打包机&#xff09; 注意:需要有对应的权…

跟着森老师学React Hooks(1)——使用Vite构建React项目

Vite是一款构建工具&#xff0c;对ts有很好的支持&#xff0c;最近也是在前端越来越流行。 以往的React项目的初始化方式大多是通过脚手架create-react-app(本质是webpack)&#xff0c;其实比起Vite来构建&#xff0c;启动会慢一些。 所以这次跟着B站的一个教程&#xff0c;使用…

关于卷积神经网络的步幅(stride)

认识步幅&#xff08;stride&#xff09; 卷积核从输入数组的最左上方开始&#xff0c;按从左往右、从上往下的顺序&#xff0c;依次在输入数组上滑动&#xff0c;我们将每次滑动的行数和列数称为步幅。 计算步幅 假设输入的形状n∗n&#xff0c;卷积核的形状为f∗f&#xff0…

手动关闭PS中的TopazStudio2的登录窗口

2021 adobe photoshop Topaz Studio 2 不是使用防火墙出站规则&#xff0c;是手动关闭的解决方案 点击社区-切换用户&#xff0c;登录窗口会出现X&#xff0c;可以手动关闭

[论文阅读]PV-RCNN++

PV-RCNN PV-RCNN: Point-Voxel Feature Set Abstraction With Local Vector Representation for 3D Object Detection 论文网址&#xff1a;PV-RCNN 论文代码&#xff1a;PV-RCNN 简读论文 这篇论文提出了两个用于3D物体检测的新框架PV-RCNN和PV-RCNN,主要的贡献如下: 提出P…

Gorm 中的钩子和回调

一个全面的指南&#xff0c;利用 GORM 中的钩子和回调的力量&#xff0c;为定制的数据库工作流程 在数据库管理领域&#xff0c;定制化是打造高效和定制化工作流程的关键。GORM&#xff0c;这个充满活力的 Go 对象关系映射库&#xff0c;为开发人员提供了钩子和回调的功能&…

二进制搭建及高可用 Kubernetes v1.20

目录 一、实验规划&#xff1a; 二、操作系统初始化配置&#xff1a; 1. 关闭防火墙 selinux&#xff1a; 2. 关闭swap分区&#xff1a; 3. 根据规划设置主机名&#xff1a; 4. 所有主机添加hosts&#xff1a; 5. 调整内核参数: 6. 时间同步: 三、部署 etcd 集群&#xff1a…

Microsoft Dynamics 365 CE 扩展定制 - 7. 安全

在本章中,我们将介绍以下内容: 构建累积安全角色配置业务单元层次结构基于分层位置配置访问配置和分配字段级安全组建团队并共享设置访问团队对静止数据进行加密以满足FIPS 140-2标准管理Dynamics 365在线SQLTDE加密密钥简介 Dynamics 365是一个强大的平台,具有超过10年的良…

数据库数据迁移常见方式

数据库数据迁移常见方式 数据库数据迁移常见方式1、通过sql2、通过数据迁移工具3、云服务进行数据迁移什么是DRS服务如何使用DRS服务DRS云服务可以干什么 数据库数据迁移常见方式 1、通过sql 批量导入sql insert into tableName select * 2、通过数据迁移工具 在数据库里面…

【ES分词】

分词 #测试分词器 POST /_analyze {"text": "小米手机和华为手机都是国产mobilephone", "analyzer": "english" }不管analyzer是改成&#xff1a;standard还是chinese都无法实现中文分词。 处理中文分词一般采用IK分词器 安装链接&…