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

【算法导论】最大子数组问题的三种解法 【算法导论】最大子数组问题的三种解法 标签(空格分隔):【算法导论】 首先补充两个数学公式: 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)将子问题的解组合成原问题的解。 ... 阅读详情

相关推荐

盘点天才少年稚晖君彭志辉的知识体系

一个杰出工程师的工作区间和装备

曲折旅程,艰难人生 2万+

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

最大子数组问题 最大子数组问题是寻找数组中和最大的非空连续子数组,这样的连续子数组为最大子数组。 使用分治策略的求解方法 首先是分解问题,把数组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

【photoshop CEP插件】 OCR文字识别

一个photoshop CEP插件OCR文字识别 APP_ID = 17594920 API_KEY = puMFv72xqCYV2jdcSlXgtFvm SECRET_KEY = v5XHtqKXEm0p6ehPZrXIXrftDvocyv1m /*********************************************/ 百度OCR 密钥由Greless@qq.com 提供, 用户可自行前往https://ai.baidu.com/docs#/Auth/top 申请。 通用文字识别..

Greless的后花园 6490

最大子数组问题

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

JIANG_RZJ的博客 1227

无监督学习初探:K-Means聚类与主成分分析(PCA)

K-Means适用于快速分组,但对数据分布敏感,可结合轮廓系数评估质量。PCA通过特征值分解实现线性降维,需注意非线性场景的替代方案(如UMAP)。进阶方向:聚类:谱聚类、高斯混合模型(GMM)处理复杂形状。降维:t-SNE、自编码器处理非线性结构。

weixin_69882801的博客 1453

手把手教你用Kokoro-82M-v1.1-zh搭建本地TTS服务(含WebSocket接口)

本文详细介绍了如何使用Kokoro-82M-v1.1-zh模型搭建本地TTS服务,包括环境配置、模型部署、WebSocket接口实现及性能优化。通过实战指南,开发者可以快速掌握本地部署TTS系统的关键技术,提升语音交互应用的开发效率。

weixin_30776273的博客 183

和最大的非空子数组(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

6、基因组数据可视化与甲基化分析:从基础操作到深入洞察

本文详细介绍了基因组数据可视化和全基因组DNA甲基化分析的方法和技术,包括基因组查看器(IGV)的基本操作、单核苷酸变异的可视化、DNA甲基化与CpG岛的关联分析、统计建模与显著甲基化区域识别,以及不同细胞系之间的甲基化模式差异分析。通过具体案例展示了如何利用MATLAB进行数据分析和可视化,为基因组研究、疾病机制探索及个性化医疗提供了技术支撑和实践参考。

qsc901234的博客 295

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

【AI应用实战-claude】在飞书上接入claudecode进行远程使用(十三)

本文介绍了三种将ClaudeCode接入飞书的方案,包括官方飞书CLI工具(推荐)、cc-connect中转工具和MCP协议集成。官方飞书CLI适合自动化办公场景,通过简单配置即可实现消息发送和文档管理;cc-connect适用于远程调用Claude功能,通过飞书群聊触发响应;MCP协议则适合开发者构建复杂工作流。文章提供了详细的操作步骤,并针对不同使用场景给出了选择建议。

1013

XCP实战系列介绍07-使用ASAP2 Editor生成A2l文件详解

介绍通过ASAP2 Editor工具生成A2l文件步骤详解

initiallizer的博客 7298

连续子数组最大和

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

SAP RAP学习系列合集介绍

《SAP RAP学习系列合集:从入门到部署的完整指南》摘要: 本文介绍了作者创建的SAP RAP学习系列合集,涵盖RAP开发从基础概念到实战部署的全流程。系列目前包含17篇文章,系统讲解了RAP核心开发技术:从数据建模、UI构建到行为定义(包括并发控制、草稿功能、授权验证等),最后详细演示了应用部署到Fiori Launchpad的两种方案(OP版和ES版)。

DeveloperMrMeng的博客 1490

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

#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

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

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

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

Pandamentle的博客 763

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

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

例如我们在求解下面的最大子数组时 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

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

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、付费专栏及课程。

余额充值