算法导论之三最大子数组问题

【算法导论】最大子数组问题的三种解法 【算法导论】最大子数组问题的三种解法 标签(空格分隔):【算法导论】 首先补充两个数学公式: alogbc=clogbaa^{log_bc} = c^{log_ba}alogb​c=clogb​a log(n!)=Θ(nlogn)log(n!) = \Theta(nlogn)log(n!)=Θ(nlogn) 什么是最大子数组问题? 给定一数组A, 寻找A中和最大的非空连续子数组。 例如: ... 阅读详情

最大子数组是数组A的和最大的非空连续子数组。只有当数组中包含负数时,最大子数组问题才有意义。注意将实际问题转化为数学问题!

使用分治策略的求解方法:

为寻找A[low..high]的最大子数组,其中央位置记为mid,然后考虑求解两个子数组A[low..mid]和A[mid+1..high]。A[low..high]的任何子数组A[i..j]所处的位置必然是以下三种情况之一:

1. 完全位于子数组A[low..mid]中,因此low <= i<= j <=mid。

2. 完全位于子数组A[mid+1..high]中,因此mid < i<= j <= high。

3. 跨越了中点,因此low <= i <= mid < j <= high。

 

实际上,A[low..high]的最大子数组必然是以上三种情况下所有子数组中的最大者。

任何跨越中点的子数组都由两个子数组A[i..mid]和A[mid+1..j]组成,只需分别找出A[i..mid]和A[mid+1..j]的最大子数组,然后将其合并即可。

以下伪代码接收数组A和下标low,mid和high作为输入,返回一个下标元组划定跨越中点的最大子数组的边界,并返回最大子数组中值的和。

FIND-MAX-CROSSING-SUBARRAY(A, low, mid,high)

left-sum = - //保存目前为止最大的和

sum = 0             //保存A[i..mid]中所有值的和

for i = mid downto low

  sum = sum + A[i]

   ifsum > left-sum        //每当找到一个子数组A[i..mid]的和大于left-sum

           left-sum = sum     //将left-sum更新为该子数组的和

           max-left = i            //更新变量max-left来记录当前下标i

right-sum = -

sum = 0

for j = mid + 1 to high

  sum = sum + A[j]

   ifsum > right-sum

           right-sum = sum

           max-right = j

return (max-left, max-right, left-sum +right-sum)

 

求解最大子数组问题的分治算法的伪代码如下:

FIND-MAXINUM-SUBARRAY(A, low, high)

if high == low             //子数组只有一个元素的情况

         return(low,high,A[low]) 

else mid =        //划分子数组,计算中点下标mid

         //递归求解左右子数组中的最大子数组

         (left-low,left-high,left-sum)= FIND-MAXINUM-SUBARRAY(A, low, mid)

         (right-low,right-high,right-sum)= FIND-MAXINUM-SUBARRAY(A, mid+1, high)

         //求跨越中点的最大子数组

         (cross-low,cross-high,cross-sum)= FIND-MAX-CROSSING-SUBARRAY(A,low,mid,high)

         //      检测最大子数组位于左子数组,右子数组还是跨越中点的数组

         ifleft-sum >= right-sum and left-sum >= cross-sum

                   return(left-low,left-high,left-sum)

         elseifright-sum >= left-sum and right-sum >= cross-sum

                            return(right-low,right-high,right-sum)

         elsereturn(cross-low,cross-right,cross-sum)

 

对应的C++程序代码如下:

#include <iostream>

 

int Find_MAX_CROSSING_SUBARRAY(int *A,intlow,int mid,int high,int& max_left,int& max_right,int& max_value)

{

         intleft_sum= -1000000;//不可能的最小值

         intsum = 0;

 

         for(inti= mid;i>low;i--)

         {

                   sum= sum+A[i];

                   if(sum>left_sum)

                   {

                            left_sum= sum;

                            max_left=i;

                   }

         }

 

         intright_sum = -1000000;//不可能的最小值

         sum=0;

 

         for(intj=mid+1;j<high;j++)

         {

                   sum= sum+A[j];

                   if(sum>right_sum)

                   {

                            right_sum= sum;

                            max_right=j;

                   }

         }

 

         max_value= left_sum+right_sum;

         return0;

}

 

int Find_MaxiMum_SubArray(int *A,intlow,int high,int& max_left,int& max_right,int& max_value)

{

         if(high==low)

         {

                   max_left  = low;

                   max_right= high;

 

                   max_value= A[low];

         }

         else

         {

                   intmid=(low+high)/2;

 

                   inttmp_left_low;

                   inttmp_left_high;

                   inttmp_left_sum;

 

                   Find_MaxiMum_SubArray(A,low,mid,tmp_left_low,tmp_left_high,tmp_left_sum);

 

                   inttmp_right_low;

                   inttmp_right_high;

                   inttmp_right_sum;

 

                   Find_MaxiMum_SubArray(A,mid+1,high,tmp_right_low,tmp_right_high,tmp_right_sum);

 

                   inttmp_cross_low;

                   inttmp_cross_high;

                   inttmp_cross_sum;

 

                   Find_MAX_CROSSING_SUBARRAY(A,low,mid,high,tmp_cross_low,tmp_cross_high,tmp_cross_sum);

 

                   if((tmp_left_sum>=tmp_right_sum)&&(tmp_left_sum>=tmp_cross_sum))

                   {

                            max_left    = tmp_left_low;

                            max_right   = tmp_left_high;

                            max_value   = tmp_left_sum;

                   }

                   elseif((tmp_right_sum>=tmp_left_sum)&&(tmp_right_sum>=tmp_cross_sum))

                   {

                            max_left    = tmp_right_low;

                            max_right   = tmp_right_high;

                            max_value   = tmp_right_sum;

                   }

                   else

                   {

                            max_left    = tmp_cross_low;

                            max_right   = tmp_cross_high;

                            max_value   = tmp_cross_sum;

                   }

 

         }

 

         return0;

}

 

int B[16] ={13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7};

 

int main()

{

 

         std::cout<<std::endl;

 

         intmax_left,max_right,max_value;

         Find_MaxiMum_SubArray(B,0,16,max_left,max_right,max_value);

         std::cout<<max_left<<"\t"<<max_right<<"\t"<<max_value<<std::endl;

         std::cout<<std::endl;

         system("pause");

         return0;

} 

《算法导论》第4章 分治策略(递归,最大子数组问题,矩阵的Strassen乘法) (最近在自己学习《算法导论》一本书,之前本来喜欢手写笔记,但是随即发现自己总是把笔记弄丢,所以打算做一个电子版的笔记) (另外书中用的都是伪代码,笔记中如果需要尝试的地方都是python代码) 分治策略:递归地求解问题,往往可以分为三个步骤: 分解(Divide)将问题划分为一些子问题,子问题的形式与原问题一样,只是规模更小。 解决(Conquer)递归地求解出子问题,如果子问题的规模足够小就直接求解 合并(Combie)将子问题的解组合成原问题的解。 ... 阅读详情

相关推荐

海上AI导航系统:技术架构与行业应用解析

计算机视觉与强化学习技术在海上导航系统中的应用正逐步改变传统航运业。通过多模态传感器融合技术,现代AI导航系统能够实现高精度的物体识别与实时路径规划,有效解决能见度依赖、决策延迟等核心痛点。以Orca AI的SeaPod系统为例,其结合了NVIDIA GeForce RTX 4070的边缘计算能力与多光谱协同识别技术,在恶劣环境下仍能保持稳定性能。这类系统不仅提升了航行安全性,还通过优化航线显著降低燃油消耗,在东京湾、马六甲海峡等繁忙水域展现出巨大价值。随着毫米波雷达融合方案的测试推进,未来海上导航将突破极

weixin_33597080的博客 354

第四章、分治策略 -- 最大子数组问题

最大子数组问题 最大子数组问题是寻找数组中和最大的非空连续子数组,这样的连续子数组为最大子数组。 使用分治策略的求解方法 首先是分解问题,把数组A[low…high]A[low…high]A[low…high]划分成两个规模尽量相等的子数组A[low...mid]A[low...mid]A[low...mid]跟A[mid+1...high]A[mid+1...high]A[mid+1...hig...

maijia0754的博客 496

PaddleOCR SVTRv2中文识别模型训练全流程:从数据准备到推理部署

本文详细介绍了基于PaddleOCR的SVTRv2中文识别模型从数据准备、模型训练到推理部署的全流程实战。SVTRv2凭借其单视觉Transformer架构和分层混合机制,在中文文字识别任务上实现了高精度与效率的平衡。文章重点解析了数据工程、训练调优技巧及部署优化方案,帮助开发者构建定制化的OCR解决方案。

weixin_29194817的博客 287

最大子数组问题

假设有一个n长度的数组, 求数组中最大的非空子数组.即子数组各个元素相加之和最大 思路1 使用分治策略求解, 找到数组的中间位置mid, 定义两边位置为left, right; 在A[left, right] 中 要求解的子数组必然是以下三种情况之一: 1.最大连续子数组在 A[left, mid] 的子数组中 2.最大连续子数组在 A[mid+1, right] 的子数组中 3.最大...

JIANG_RZJ的博客 1227

MS建模mmt

一、流程:1.定义好每个原子力场类型:Edit Sets(分组) 2.加H(一般是仅与Al-O八面体中的Al相连的O原子)、给H分组 3.“make P1”、校核化学式(正确与否) 4.扩成超晶胞(Na-mmt:4*1*1,Ca-mmt:4*2*1,illite:2*1*1,由化学式而定) 5.置换阳离子: mmt:模型中每 32 个 Si 4+有 1 个被 Al 3+ 取...

weixin_30721899的博客 2174

100kHz手持LCR表设计:高频阻抗测量与校准实战解析

阻抗测量是电子元件测试的基础,LCR表通过施加正弦激励并分析电压电流的幅值与相位,即可获取电容、电感、电阻的等效参数。在开关电源、无线充电等高频应用场景中,元件在100kHz下的ESR和阻抗特性尤为关键,传统10kHz手持仪表难以满足需求。本文从自动平衡桥原理出发,探讨如何将台式电桥的核心能力浓缩至手持设备,重点剖析高频寄生参数抑制、模拟链路设计、数字相敏检波算法及开路短路校准方法。通过实测数据验证,在100kHz频率下基本精度可达0.5%以内,为维修现场、产线抽检及硬件调试提供了可携带的精密测量方案。全文

weixin_33910191的博客 397

和最大的非空子数组(scala版本)

给定一个整数数组,求它的子数组(连续)里面最大的和是多少 算法思路来自于:http://www.julyedu.com/video/play/id/19 中思路四,代码相对迭代算法简单很多,思路也容易理解,我谨将C++算法转换成scala算法,其他思路请到七月算法中查看,如有错误请指正。 object test{ val a = Array(1,-2,3,-20,-5,4,5,4,5)

wangzfox的博客 548

Open3D 可视化(1)——简单可视化【2026最新版】

简单可视化,博客长期更新,本文最新更新时间为:2026年5月10日。

点云侠的博客 5685

python数组的一些特殊表示

python中会使用“:”等符号对数组进行简化表示,如 1. x[:,n] 表示一个数组中第一维取所有数据,第二维取下标为n的数据,即取第二维下标为n的所有数据 eg: x=np.array([[1,1,2],[2,1,3],[3,1,2],[3,3,3],[3,3,2],[1,0,1]]) print("x[:,1]:",x[:,1],"x[:,2]:",x[:,2]) #输出:x3[:,1]...

waq127520的博客 2641

【Realtek sdk-3.4.14b】RTL8197FH+RTL8363NB当WAN/LAN IP冲突的时候,再次切换回正常的WAN,出现电脑无法上网也无法ping通设备网关问题分析及解决方案

如上图所示,当WAN和LAN网段冲突的时候,会导致路由设备异常,无法上网,但是修改为不冲突的网段之后,依然无法上网,同时下级PC也无法ping通路由设备,正常的如下图所示如上图所示,正常网络拓扑是可以正常的,但是在上级和路由LAN冲突的时候,再次切换为正常的网络也是异常问题复现步骤1.路由设备WAN口接到一个和本级路由是相同网段的设备2.拔掉WAN口,将WAN口接到一个和本级路由是不同网段的设备3.此时PC无法访问路由器。

wgl307293845的博客 665

刚体转动欧拉方程:从理论到卫星姿态控制的实践

刚体转动欧拉方程是描述刚体旋转运动的基本动力学方程,在卫星姿态控制、机器人学、航空航天等领域有着广泛应用。本文将详细讲解欧拉方程的物理概念、数学推导、数值计算方法,并重点分析其在卫星姿态控制系统中的具体应用。

ScilogyHunter的博客 642

连续子数组最大和

package com.yimu.test; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.Arrays; public class D { // 给定一个长度为 n 的数组,数组中的数为整数。 // 请你选择一个非空连续子数组,使该子数组所有数之和尽可能大。求这个最大值。 public static void.

Xiaojia_guniang的博客 968

库存管理系统项目部署方案(基于jdk8)

不需要安装到服务器,运维本地安装就行,主要是用来编译前端代码的。构建完成后将dist文件夹复制到服务器内。

程序员诚哥 2574

【算法导论】最大子数组问题

#include #define LENGTH 16 //定义一个结构,记录了左右下表和总和,原因在于用于数据返还 typedef struct { int low; int high; int sum; }parm; parm findMaxCrossingSubarray(int number[],int low,int mid,int high)

Code for Yun 2553

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

算法导论之最大子数组问题 C语言实现

算法导论之最大子数组问题 C语言实现

Pandamentle的博客 763

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

算法导论之最大子数组问题

例如我们在求解下面的最大子数组时 13 -3 -25 20 -3 -16 -23 18 20 -7 12 -5 -22 15 -4 7     最简单的做法就是暴力求解,但是时间复杂度为O(n^2); // // main.cpp // 算法导论 // // Created by SJCH...

SJCHEN1221的博客 478

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

Java动态规划解决最大子数组问题,线性时间复杂度。(算法导论4.1)

package 最大子数组; import java.util.Arrays; /* * 动态规划方法解决最大子数组问题 * */ public class Solution { public static void main(String[] args) { // TODO 自动生成的方法存根 int[] arr = new int[] {13,-3,-25,20,-3,-...

qq_34553282的博客 786

算法导论--最大子数组问题

最大子数组问题: 问题描述:   假定你获得了投资挥发性化学公司的机会。与其生产的化学制品一样,这家公司的股票价格也是不稳定的。你被准许可以在某个时刻买进一股该公司的股票,并在之后某个日期将其卖出,买进卖出都是在当天交易结束后进行。为了补偿这一限制,你可以了解股票将来的价格。你的目标是最大化收益。 虽然最高价卖出,最近价买进是收益最大化,但是在一段给定时期内,可能无法做到在最低价格时买进股票...

jiangbinbin的博客 527

算法导论——分治策略——最大子数组问题

最大子数组:一个数组A的和最大的非空连续子数组。 注意:只有当数组中包含负数时,最大子数组问题才有意义。 暴力求解法:(对每个子数组求和,选出和最大的子数组) 分治策略求解方法: 将数组分成规模尽可能相等的子数组,即找到中间位置,然后考虑左子数组和右子数组,最大子数组位置必然有以下三种情况: 完全位于左子数组中 2) 跨过了中点 3) 完全位于右子数组中 分别求出三种情况下的最大子数组,再选出三...

weixin_45115866的博客 620

算法导论之求解最大子数组问题python代码实现

算法导论之最大子数组问题 使用分治策略求解 基于python的源代码如下: #求出跨越中点的最大子数组 def FIND_MAX_CROSSING_SUBARRARY(list,low,mid,high): left_max = -float("inf") right_max = -float("inf") left_sum = 0 right_sum = 0 left_index = ...

weixin_45184423的博客 356

最大子数组问题--算法导论

if sum > left-sum //找出和最大的组合,赋值给left-sum,并且将下标赋给max-left。求左边和右边的最大子数组是在递归中可以由求中间的最大子数组求出,看到后面的分解过程就会明白了,我们主要解决求中间的最大子数组问题。FIND-MAX-CROSSING-SUBARRAY(A, low ,mid , high) //输入数组和左中右的下标。//找到了左边和右边的最大组合,返回左边下标和右边小标以及找出的跨越中间的最大数组的值。//同左边的操作相同。

Hennan_Dianzi_C的博客 1788

算法导论————最大子数组问题(C,Java,python)

我们来思考如何用分治技术来求解最大子数组问题。假定我们要寻找子数组A[ lorw. . high]的最大子数组。使用分治技术意味着我们要将子数组划分为两个规模尽量相等的子数组。也就是说,找到子数组的中央位置,比如mid,然后考虑求解两个子数组A[low. . mid]和A[mid+1.. high]。

qq_52659550的博客 1211

算法导论 — 4.1 最大子数组问题

笔记 本节给出了分治法的一个例子。给定一个数组A[1..n]A[1..n]A[1..n],找出一个元素和为最大的连续子数组A[i..j]A[i..j]A[i..j],其中1≤i≤j≤n1 ≤ i ≤ j ≤ n1≤i≤j≤n,称这样的子数组为最大子数组。例如,下图所示数组中,第888个元素到第111111个元素之间的子数组为最大子数组。      求解最大子数组问题,最简单的方法是暴力检查所有的子...

yangtzhou的专栏 2058

Java实现《算法导论》最大子数组问题

算法导论第四章分治策略38页最大子数组问题Java实现,算法见书中 public class Main { static class Result { public int left; public int right; public int maxSum; public Result(int left, int right, int maxSum) { thi

Silence_1992w的博客 557

算法导论——最大子数组问题

方法一: 暴力求解 #include #include #include int maxsubset(int *a,int len){ int summax=INT_MIN; int i,j,k; for(i=0;i<len;i++) for(j=i;j<len;j++){ int temp=0;

182
上一篇: 算法导论之一插入排序
下一篇: 算法导论之四矩阵乘法的Strassen算法
mengrennwpu
博客等级 码龄15年 262粉丝 87原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mengrennwpu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值