题目:
输入一个整形数组,数组里有正数也有负数。
数组中连续的一个活多个整数组成一个子数组,每个子数组都有一个和。
求所有子数组的和的最大值。要求时间复杂度是O(n).
这道题目如果没有时间复杂度的限制的话,那一分钟便可以写出来。因为三层for循环,使用穷举法,便可以直接求的最大值。这样的话时间复杂度就是N^3,但是如果是O(N)的话,那么就必须要求只有一次for循环。那么应该组织代码才能求出这个最大子数组和呢?
其实思想很简单,那就是从头开始遍历数组,如果不断累加数组的各个元素。如果出现和小于0的情况,那么能说明一个问题:最大子数组一定不包括已经求得和的子数组。那么应该从当前位置重新求子数组。如果出现和比旧的记录大的情况,就更新最大值。
程序如下所示:
#include<iostream>
using namespace std;
int a[] = {4,-9,5,6,-2,-3,8,9,9,-7,-9,8};
struct Result{
int start;
int length;
int result;
};
Result maxSum(int* a,int n){
Result result;
int b = 0;
result.start = 0;
result.length = 0;
result.result = 0;
for(int i=0;i<n;i++){
if(b<0){
b = a[i];
result.start = i;
result.length = 1;
}
else{
b += a[i];
result.length ++;
}
if(result.result < b){
result.result = b;
}
}
return result;
}
int main(){
Result result = maxSum(a,sizeof(a)/sizeof(int));//注意这里求数组长度的方法
cout<<result.length<<endl;
cout<<"The max-sum sub array is as follows:"<<endl;
for (int n=result.start; n<result.start+result.length; n++)
{
cout<<a[n]<<" ";
}
cout<<endl<<"The max sum is :"<<endl;
cout<<result.result<<endl;
}