带你吃透分治算法 (一)最大子数组

您所在的位置:网站首页 数组中的最大值递归法 带你吃透分治算法 (一)最大子数组

带你吃透分治算法 (一)最大子数组

2024-06-28 15:04:22| 来源: 网络整理| 查看: 265

分治算法

分治算法的基本思想是将一个规模为N的问题分解为K个规模较小的子问题,这些子问题相互独立且与原问题性质相同。求出子问题的解,就可得到原问题的解。就像归并排序的排序思想一样。

回忆一下归并排序的过程,我们在递归地求解一个问题时,在每层递归中应用了以下三个步骤:

分解:将原问题划分为子问题,子问题的形式(性质)和原问题一样,只是规模变小了解决:当子问题的规模非常小了(如递归排序中排序元素只有一个时),则停止递归,直接进行求解。合并:将划分的两个子问题的解组合成原问题的解,不过有时我们会遇到需要求解与原问题不完全一样的子问题,我们也将其求解过程看做合并步骤的一部分。

因此,从上面的思路我就便定义了两种情况:

递归情况:当子问题很大,需要递归求解的情况基本情况:子问题小到了一定的程度时(触底了),不再需要递归的情况 分治思想解最大子数组问题

最大子数组问题:给定一个整数数组,要求找出元素之和最大的子数组。即给你一个数组Arr[a1,a2,a3…,an],求下标j,k,使得sum = a(j)+a(j+1)+a(j+2)+…+a(k)为最大值。

首先我们知道,只有数组中包含负数时,最大子数组问题才有意义,如果所有的数组元素都是非负的,那么最大子数组便是其本身。

对于最大子数组问题,有许多解法,如暴力穷举法,动态规划法等等,我们因为是为了学习分治的思想,因此主要讲用分治思想解最大子数组,其他方法可以参考如下博文:最大子数组及其优化

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

加入给你如下数组A[13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7],则最大子数组如下图所示:

在这里插入图片描述

下面我们来思考如何使用分治思想求解最大子问题,如过我们将原数组以其中心划分为两部分A[low,…,mid]和A[mid+1,…,high],则我们要寻找的最大子数组一定只有三种可能位置。

最大子数组完全位于左半边A[low,…,mid]。最大子数组完全位于右半边A[mid+1,…,high]。最大子数组两边都占据了一些位置。

如下图所示: 在这里插入图片描述 在这里插入图片描述

因此,我们可以递归地对前两种可能性求解,因为这两个子问题仍是最大子数组问题,只是规模相比较原数组更小,之后便是寻找跨越中点的最大子数组,然后在这三种情况中选取最大者。

对于跨越中点的最大子数组的求法,我们可以将这个数组A[i,…,mid,…,j]划分为两部分A[i,…,mid]和A[mid+1,…,j],当这两部分分别为两边的最大子数组时,那么其合并起来的A[i,…,mid,…,j]即为跨越两边的最大子数组。

C语言实现:

//结构类型定义 typedef int ElemType; typedef struct MaxSubarray{ int l_index,r_index; ElemType Sum; }MaxSubarray; //跨越两边的最大子数组求解 MaxSubarray Get_CrossMaxSubArray(ElemType arr[],int left,int mid,int right) { MaxSubarray MSArray; ElemType Sum_temp = INT_MIN; ElemType Sum_l=0,Sum_r=0; for(int i=mid;i>=left;i--)//找左半部最大子数组 { Sum_l += arr[i]; if(Sum_l > Sum_temp) { Sum_temp = Sum_l; MSArray.l_index = i; } } MSArray.Sum = Sum_temp; Sum_temp = INT_MIN; for(int i = mid+1;i Sum_temp = Sum_r; MSArray.r_index = i; } } MSArray.Sum += Sum_temp; return MSArray; }

解决了这个问题,那么接下来就简单了,按照上面讲的不断划分直到“触底”,然后寻找跨越两边的最大子数组,将三者比较返回最大的子数组。

//分治策略求解最大子数组问题 MaxSubarray GetMaxSubArray_Divide(ElemType arr[],int left,int right) { MaxSubarray MSArray_left,MSArray_mid,MSArray_right; if(left == right) { MaxSubarray TEMP; TEMP.l_index = left; TEMP.r_index = right; TEMP.Sum = arr[left]; return TEMP; }else { int mid = (left + right)/2; MSArray_left = GetMaxSubArray_Divide(arr,left,mid); MSArray_right = GetMaxSubArray_Divide(arr,mid+1,right); MSArray_mid = Get_CrossMaxSubArray(arr,left,mid,right); if(MSArray_mid.Sum >= MSArray_left.Sum && MSArray_mid.Sum >= MSArray_right.Sum)//寻找最大值 return MSArray_mid; else if(MSArray_left.Sum >= MSArray_right.Sum && MSArray_left.Sum >= MSArray_mid.Sum) return MSArray_left; else return MSArray_right; } }

分治算法解最大子数组的时间复杂度为O(n*log n),但是实际上还存在一个线性时间的算法,可参考最大子数组问题及其优化



【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭