求 最大连续字串和、积这个题目是在早期庞果的两个题目,由于这两个题目实现非常相似,所以我就将他们合并一起一起讨论了。
(1)最大字串和;
最大连续子串和问题是求一个整数串中的和,比如串A={1,2,-3,4,10,-5,-7,100,-8,9,-100},求串A的最大子串和。题目的大概意思就这样了。下面分析吧!
- 分析:其实碰到这道题我已开始就想到用枚举方法求解了,但是时间复杂度比较大O(n3)。对于枚举方法就不多说了,下面给出程序:
#include<stdio.h>
#include<string.h>
int zxpjzzc(int a[],int n)
{
int i;
枚举法,时间复杂度为O(n3)
int max=a[0];
int temp=0;
int t,j,k,strj=0,endj=0;
for (i = 0; i <n; i++)
{
for (j = i; j <n; j++)
{
for (k = i; k <=j; k++)
{
temp+=a[k];
}
if (max<temp)
{
max=temp;
strj=i;
endj=j;
}
temp=0;
}
}
printf("最大子串:");
while (endj>=strj)
{
printf("%d ",a[strj]);
strj++;
}
return max;
}
void main()
{
int a[]={1,2,-3,4,10,-5,-7,100,-8,9,-100};
printf("\n算法2:%d",zxpjzzc(a,10));
}
2. 分析:现在用一个优化的方法,使其时间复杂度为O(n)。我们可以知道,假如前面的一个数大于等于0,则将它往下相加,那么将会得到一个新的数组,最后从数
组中取出最大值就是所求的最大值。
算法思想:(1)设一个临时变量max=a[0],然后判断max是否大于0,若是,则a[i]+=max(其中1<=i<n);否则,令max=0。
(2)继续使max=a[0],求数组a[n]的最大值就是所求的最大值。
算法实现:
#include<stdio.h>
#include<string.h>
//#include<stdlib.h>
int r[10] = {0};
int p = 0;
void zxpjzzc(int a[],int n)
{
int i;
//时间复杂度为O(n)
int max = a[0];
for (i = 1; i <n; i++)
{
if (max>=0)
{
a[i] += max;
max = a[i];
}
else
{
max = 0;
}
}
max = a[0];
for ( i = 0; i < n; i++)
{
//printf("%3d ",a[i]);
if (max<a[i])
{
max = a[i];
}
}
r[p] = max;
p++;
}
int main()
{
int i = 0, N, n;
scanf("%d", &N);
int *a;
while (i < N)
{
scanf("%d", &n);
a = new int[n];
for (int j = 0; j < n; j++)
{
scanf("%d",&a[j]);
}
zxpjzzc(a, n);
memset(a,0,sizeof(a));
i++;
}
for (int i = 0; i < N; i++)
{
printf("%d\n",r[i]);
}
//system("pause");
return 0;
}
(2)最大连续子串积,这个不多说了。我用的是枚举法求解。
实现代码如下:
#include<stdio.h>
int zxpjzzc(int a[],int n)
{
int max=a[0];
int temp=1;
int i,j,k,strj=0,endj=0;
for (i = 0; i <n; i++)
{
for (j = i; j <n; j++)
{
for (k = i; k <=j; k++)
{
temp*=a[k];
}
if (max<temp)
{
max=temp;
strj=i;
endj=j;
}
temp=1;
}
}
//printf("最大子串:");
//while (endj>=strj)
//{
// printf("%d ",a[strj]);
// strj++;
//}
return max;
}
void main()
{
int a[]={1,2,-3,4,-1,-5};
printf("\n最大积:%d",zxpjzzc(a,6));
}