【算法设计-分治】最大子数组问题

1.问题描述

算法导论上38页,最大子数组给出一组数组来,然后求出使得从i到j的数组值的和最大的边界i与j。如果不用分治的方法的话,需要通过暴力方法来寻找n(n-1)/2种。

方法:

2代码:

#include<iostream>

using namespace std;

typedef struct maximum

{

int left;

int right;

int sum;

}Maximum;

Maximum* FIND_MAX_CROOSING_SUBARRAY(int *A,int low,int mid,int high);

Maximum* FIND_MAXIMUM_SUBARRAY(int *A,int low,int high);

Maximum* FIND_MAX_CROOSING_SUBARRAY(int *A,int low,int mid,int high)

{

Maximum *mymaximum=new Maximum;

int left_sum=INT_MIN;

int right_sum=INT_MIN;

int i,j;

int sum=0;

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

{

sum=sum+A[i];

if(sum>left_sum)

{

left_sum=sum;

mymaximum->left=i;

}

}

sum=0;

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

{

sum=sum+A[j];

if(sum>right_sum)

{

right_sum=sum;

mymaximum->right=j;

}

}

mymaximum->sum=left_sum+right_sum;

return mymaximum;

}

Maximum* FIND_MAXIMUM_SUBARRAY(int *A,int low,int high)

{

int mid;

Maximum *leftmymaximum=new Maximum;;

Maximum *rightmymaximum=new Maximum;

Maximum *mycross=new Maximum;

if(low!=high)

{

mid=(low+high)/2;

leftmymaximum=FIND_MAXIMUM_SUBARRAY(A,low,mid);

rightmymaximum=FIND_MAXIMUM_SUBARRAY(A,mid+1,high);

mycross=FIND_MAX_CROOSING_SUBARRAY(A,low,mid,high);

}

if(((leftmymaximum->sum)>=(rightmymaximum->sum))&&((leftmymaximum->sum)>=(mycross->sum)))

return leftmymaximum;

else if((rightmymaximum->sum)>=(leftmymaximum->sum)&&(rightmymaximum->sum)>=(mycross->sum))

return rightmymaximum;

else

return mycross;

}

int main(void)

{

int totalnum;

int i=1;

int t;

int *A=new int;

Maximum *mymaximum=new Maximum;

printf("您的数组一共有多少个数字?\n");

scanf("%d",&totalnum);

printf("请输入您要输入的数组?以-123\n");

for(i=1;i<=totalnum;i++)

scanf("%d",&A[i]);

mymaximum=FIND_MAXIMUM_SUBARRAY(A,1,totalnum);

printf("最大子数组的左边界是%d\n",mymaximum->left);

printf("最大子数组的右边界是%d\n",mymaximum->right);

printf("最大子数组的和是%d\n",mymaximum->sum);

return 0;

}

结果:

时间: 2024-10-09 13:51:36

【算法设计-分治】最大子数组问题的相关文章

针对范围对的高效查找算法设计(不准用数组)

题目链接在:针对一群范围对的最快查找算法设计(不要用数组),是我目前遇到的一个较棘手的问题. 描述如下: 假如有一群范围对,格式为:<范围表示,该范围对应的结果值>,设计一个最快查找算法,使得给定一个值,输出该值所在范围对的结果值. 注意:范围对之间没有交集,即不可能存在<1, 10>和<2, 11>这样的两个范围对. 例如有以下几个范围对: <<1, 2>, 20> <<3, 37>, 27> <<48, 5

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

寻找数组A的和最大的非空连续子数组.例如:int A[] = {1, -2, 3, 10, -4, 7, 2, -5}的最大子数组为3, 10, -4, 7, 2,其最大和为18. 方法1:枚举所有子数组并求出他们的和. 长度为n的数组有O(n2)个子数组(即:n + n-1 + ... + 1=n(n+1)/2):而且求一个长度为n的数组的和的时间复杂度为O(n).因此这种思路的时间复杂度是O(n3). 1 #include <iostream> 2 #include <vector&

【算法导论】最大子数组

1.描述:找出数组A的和最大的非空连续子数组,我们称这样的连续子数组为最大子数组. 2. 用分治策略来求解. a. 假设我们要求A的子数组A[low, high]的最大子数组.根据分治策略,我们先将A[low,high] 平分 b. 那么 A[low,highj]的子数组A[i,j]只有三种可能 a)完全位于A[low, mid]; 此时 low <= i <= j <= mid b)  完全位于A[nid+1, high]中,此时 mid + 1 <= i <= j <

算法之求最大子数组

最大字数组问题是递归与分治算法中的经典问题: 问题:求一个数组中相加可以获得最大值的子数组,子数组是指原数组中任意连续的一段 代码: #include <iostream> using  namespace std; int max_mid(int *a,int mid,int low,int high) {     int ml = a[mid];     int mr = 0;     int sum = ml;     for(int i = mid-1; i>=low; i--)

分治策略 &nbsp; 最大子数组问题

递归式 递归式与分治方法是紧密相关的,因为使用递归式可以很自然地刻画分治算法的运行时间.一个递归式就是一个等式或不等式,它通过更小的输入上的函数值来描述一个函数.例如,在2.3.2节,我们用递归式描述了MERGE-SORT过程的最坏情况运行时间T(n): Θ(1)        若n=1 T(n) =                         (4.1) 2T(n/2)+Θ(n)    若n>1 求解可得T(n)=Θ(nlgn) 递归式可以有很多形式.例如,一个递归算法可能将问题划分为规模

第八章:再谈最大子数组问题

前段时间看<算法导论>了解到最大子数组问题,但没有做习题,遗漏了一些重要的知识,现在<编程珠玑>上看到完整的讲解,还有一些算法技巧,故记录于此. 1.定义问题 在数组中找出元素之和最大的子数组,假定当数组元素全部为负数时,最大子数组是空数组,和为0. 2.解决问题 令数组为x[n],最大子数组下标为[p,q]. 2.1算法1:时间复杂度O(n3) maxsofar=0 for i=[0,n) for j=[0,n) sum=0 for k=[i,j] sum+=x[k] if(su

最大子数组问题 Maximum Subarray

Maximum Subarray 标签(空格分隔): algorithm 这个问题我们先看下问题的描述: 问题描述 Find the contiguous subarray within an array (containing at least one number) which has the largest sum. For example, given the array [?2,1,?3,4,?1,2,1,?5,4], the contiguous subarray [4,?1,2,1

第四章 分治策略 4.1 最大子数组问题 (暴力求解算法)

/** * 最大子数组的暴力求解算法,复杂度为o(n2) * @param n * @return */ static MaxSubarray findMaxSubarraySlower(int[] n) { long tempSum = 0; int left = 0; int right = 0; long sum = Long.MIN_VALUE; for (int i = 0; i < n.length; i++) { for (int j = i; j < n.length; j++

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

最大子数组问题 方法一:暴力求解方法 我们可以很容易地设计出一个暴力方法来求解本问题:简单地尝试没对可能的子数组,共有O(n2)种 #include<iostream> using namespace std; #define INT_MIN 0x80000000 int main() { int arr[10]={9,8,-3,-5,7,-39,79,-37,8,9}; int i,j; int sum=0,maxsum=INT_MIN; int imax; for(i=0;i<10;