最大子数组

xiaoxiao2021-02-28  80

题目描述

给出一个数组A[0..n-1],求数组A中和最大的连续子数组。

输入描述

第1行为一个整数N(N>0),表示数组元素个数。 第2行为数组的N个元素,每个元素为整数,相互之间用空格分隔。

输出描述

在一行中输出最大子数组的起始下标、结束下标和子数组的和,用空格分开。

输入样例

16 13 -3 -25 20 -3 -16 -23 18 20 -7 12 -5 -22 15 -4 7

输出样例

7 10 43

提示

来源or类型

思路:第一种方法:暴力求解,不知道能不能过因为我没有尝试;            第二种方法:分治法:                 #include<iostream> #include<cstdlib> #include<cstdio> #include<limits.h> using namespace std; struct XB //使用结构体输出;由于return 不能同时返回三个值; { int left; int right; int value; }; XB cross_middle(int *a,int l,int m,int r) //分治法是分成了三种情况,这就是最复杂的一种---跨越左半部分和右半部分 { XB p; int i; int sum=0; int l_max=-999999; int r_max=-999999; for(i=m;i>=1;i--) { sum+=a[i]; if(sum>l_max) { l_max=sum; p.left=i; } } sum=0; for(i=m+1;i<=r;i++) { sum+=a[i]; if(sum>r_max) { r_max=sum; p.right=i; } } p.value=l_max+r_max; return p; } XB maxsubset(int *a,int l,int r) //函数要定义为结构体形式的函数; { XB p; if(l==r) //一个元素的情况; { p.left=l; p.right=r; p.value=a[l]; return p; } int m=(l+r)/2; //开始进行分治; XB l_max=maxsubset(a,l,m); XB r_max=maxsubset(a,m+1,r); XB c_max=cross_middle(a,l,m,r); if(l_max.value>=r_max.value&&l_max.value>=c_max.value) p=l_max; else if(r_max.value >= l_max.value&&r_max.value >= c_max.value) p=r_max; else p=c_max; return p; //这样返回值就可以返回了多值,从而满足了题意; } int main() { int a[10010]; XB p; int N; cin>>N; for(int i=0;i<N;i++) scanf("%d",&a[i]); p=maxsubset(a,0,N-1); printf("%d %d %d\n",p.left,p.right,p.value); return 0; }             第三种方法:线性时间解决问题,也是最单的一种方法         #include<iostream> #include<cstdio> using namespace std; int a[100010]; int main() { int N; int flag=0; cin>>N; int Max=0,c; int Maxi=0; int Maxj=0; int sum=0; for(int i=0;i<N;i++) scanf("%d",&a[i]); for(int i=0;i<N;i++) { sum+=a[i]; if(sum>Max) { Max=sum; Maxj=i; } if(sum<0) { sum=0; } } c=Max; //想了一会 实在没有什么标记的方法了 所以就用的是种方法标记的结果; for(int i=Maxj;i>=0;i--) { c-=a[i]; if(c==0) { Maxi=i; break; } } printf("%d %d %d\n",Maxi,Maxj,Max); return 0; }   
转载请注明原文地址: https://www.6miu.com/read-81470.html

最新回复(0)