题目描述:
输入一个整形数组,数组里有正数也有负数。
数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。
求所有子数组的和的最大值。要求时间复杂度为O(n)。
例如输入的数组为1, -2, 3, 10, -4, 7, 2, -5,和最大的子数组为3, 10, -4, 7, 2,
因此输出为该子数组的和18。
思路一,暴力法。通过三层循环,找出所有子数组,求和,比较,得出最大和,时间复杂度O(n^3)
int maxsum01(int array[],int n)
{
int sum = 0;
int max = 0;
for(int i=0;imax)
max = sum;
sum=0;
}
}
return max;
}
思路二,线性遍历数组,如果将当前元素加入之后sum<=0,说明截至到该元素,往后再加元素也不会达到子数组和最大,此时将sum更换为下一个元素,每次加入新元素之后都会与现有的max进行比较,以保留最大值。时间复杂度O(n)
int maxsum02(int array[],int n)
{
int sum = 0;
int max = array[0];
for(int i=0;i=0)
{
sum += array[i];
}
else
{
sum = array[i];
}
if(sum>max)
max = sum;
}
return max;
}
思路三,利用动态规划的方法
设sum[i] 为前i个元素中,包含第i个元素且和最大的连续子数组,result 为已找到的子数组中和最大的。对第i+1个元素有两种选择:做为新子数组的第一个元素、放入前面找到的子数组。
sum[i+1] = max(a[i+1], sum[i] + a[i+1])
result = max(result, sum[i])
int maxsum03(int array[],int n)
{
int sum = array[0];
int max = array[0];
for(int i=1;i
思路是使用线性扫描,使用空间换时间,用数组b[i]保存a[0]*...*a[i-1]*a[i+1]*...a[n-1]。代码如下:
int makeArray(int a[],int b[],int n)
{
b[0]=1;
for(int i=1;i0;j--)
{
b[0] *= a[j+1];
b[j] *= b[0];//b[j]=a[n-1]*...*a[j+1]*a[j-1]*...*a[0]
}
b[0] *= a[1];
int max = -2147483647 - 1;
cout<
1 给定整型数组,其中每个元素表示木板的高度,木板的宽度都相同,求这些木板拼出的最大矩形的面积。并分析时间复杂度。
此题类似leetcode里面关于连通器的题,需要明确的是高度可能为0,长度最长的矩形并不一定是最大矩形,还需要考虑高度很高,但长度较短的矩形。如[5,4,3,2,4,5,0,7,8,4,6]中最大矩形的高度是[7,8,4,6]组成的矩形,面积为16。
解决思路:使用分治递归的方法,即在[start,end]区域计算出矩形的面积,计算左侧的面积,计算右侧的面积,找出三者中面积最大的,返回
//最大值
int MAX(int a,int b)
{
return a > b ? a : b;
}
//给定数组表示单位宽度木板的高,求最大矩形的面积
int MaxSquare(int*a,int start,int end,int &Max)
{
if(end < start)
return 0;
if(end == start)
return a[end];
int minindex = start;
for(int i = start;i <=end;i++)//每次求出区间的最小高度
if(a[i] < a[minindex])
minindex = i;
int all = a[minindex] * (end - start +1);//以最小高度的最长矩形的面积
int lf = MaxSquare(a,start,minindex -1,Max);//左区域的最大面积
int rg = MaxSquare(a,minindex +1,end,Max);//右区域的最大面积
int t =MAX(all,MAX(lf,rg));//当前区间的最大面积
Max = MAX(Max,t);
return t;
}
int MaxSquare(int*a,int n)
{
int minindex = 0;
int max = 0;
MaxSquare(a,0,n-1,max);
return max;
}
一个M*N的矩阵,找到此矩阵的一个子矩阵,并且这个子矩阵的元素的和是最大的,输出这个最大的值。如果所有数都是负数,就输出0。 例如:3*5的矩阵:
1 2 0 3 4
2 3 4 5 1
1 1 5 3 0
和最大的子矩阵是:
4 5
5 3
最后输出和的最大值17。
《
原题目给出的答案可能有问题,对于子矩阵
3 4 5
1 5 3
的值要比给出的矩阵的和要大
》
解决思路:在求最大子数组和的基础上,对于矩阵从i到j行,相加,得到一个数组,求出a[i][0-m]到a[j][0-m]之间和最大的子矩阵的和
int maxSubMatrix(int matrix[5][5],const int n,const int m)
{
int i,j,k,max=0,sum=-10000;
int b[101];
for(i=0;i sum)
{
sum = max;
}
}
}
return sum;
}
// you can also use includes, for example:
#include
int help(vector &a) {
int n = a.size();
vector f,g;
f.resize(n);
f[0] = a[0];
int now = a[0];
for (int i = 1; i < n; ++i) {
now = max(now, a[i]);
f[i] = max(a[i] + f[i - 1], now);
}
g.resize(n);
g[n - 1] = a[n - 1];
int answer = a[n - 1];
for (int i = n - 2; i >= 0; --i) {
g[i] = max(g[i + 1], 0) + a[i];
answer = max(answer, g[i]);
}
for (int i = 1; i < n; ++i) {
answer = max(answer, g[i] - a[i] + f[i - 1]);
}
return answer;
}
int solution(vector &A) {
// write your code in C++11
int answer = help(A);
for (int i = 0, j = A.size() - 1; i < j; ++i,--j) {
swap(A[i],A[j]);
}
answer = max(answer,help(A));
return answer;
}