求数组或者子数组和最大的序列
求子数组的最大和
输入一个整形数组,数组里有正数也有负数。
数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。
求所有子数组的和的最大值。要求时间复杂度为O(n)。
例如输入的数组为1, -2, 3, 10, -4, 7, 2, -5,和最大的子数组为3, 10, -4, 7, 2,
因此输出为该子数组的和18。
记得这个问题最先看见是在一次笔试中看见的,第一感觉就是,这个画图,求导,现在想想,可笑了,真是把问题复杂化了。。。
就是把阴影面积求出正的呗,结果。。。似乎没啥用处 对于解题。。
其实很简单,你用一个变量专门记录临时累加和,如果累加是正的救继续,如果出现负的,那说明最后加入的这个肯定是负的,而且这
之前的所有序列可以放弃了,可能会有人有点想不明白,这里给出证明把
假设a[0]+a[1]+....+a[i]+.......+a[j]<0 式1
那么我们的结论是这里前j个元素都可以放弃,有的人会想,是否有可能 a[i]+....a[j]>0 呢?
我们知道a[0] + a[1]+.....+a[i-]>0(否则就被我们丢弃了)
那式1看成两部分,前i-1个元素之和大于0,后半部分必须小于0 才能使得整体小于0,所以。。。
/---
补充下:这题还考察大家是否注意了:如果输入的数字全为负数的情况?我这里就默认输出0
当时就被面试官问道这个点上了,当时考虑了觉得只是一种特例,对解题没什么影响所以忽略了。。大家注意下这个特例吧
/---
//============================================================================
// Name : SubSequenceMaxSum.cpp
// Author : YLF
// Version :
// Copyright : Your copyright notice
// Description : solve the max sum of subsequence, Ansi-style
//============================================================================
#include <iostream>
using namespace std;
#define MAX 50
void subSum(int*, int);
int main() {
int arr[MAX];
int num = 0;
cin>>num;
int i=0;
for(i=0;i<num;i++)
cin>>arr[i];
subSum(arr, num);
return 0;
}
void subSum(int *arr, int n){
int i=0;
int sum = 0;//记录最大值
int tempSum = 0;//临时记录
int start=-1,end=-1;
for(i=0;i<n;i++){
if(tempSum < 0){
tempSum = arr[i];//重新开始记录
start = i;
end = i;
}else{
tempSum += arr[i];
}
if(tempSum > sum){
sum = tempSum;
end = i;
}
}
cout<<"the max subsequence:"<<endl;
for(i=start;i<=end;i++)
cout<<arr[i]<<",";
cout<<endl<<"the sum:"<<sum<<endl;
}