您的位置:首页 > 其它

笔试题:求最大连续子数组的最大乘积

2014-10-13 16:02 375 查看
注意:是连续子数组;而子序列表示原来的顺序不变,但是可以除去中间的任意元素;

思路一:

将第一个值都和后面的每个值分别相乘,相乘的过程中找出最大值;
接着讲第二个值与后面的每个值分别相乘,找出最大值;
最后将最大值在比较出最终的最大值。

时间复杂度:O(n2)

int GetMax(int a[], const int &length)
{
int i=0,j=0;
int sum=a[0];
for(i=0;i<length;i++)
{
int sum2=a[i];
for(j=i+1;j<length;j++)
{
sum2 *= a[j];
if(sum2 > sum)
sum = sum2;
}
if(sum2 > sum)
sum = sum2;
}
return sum;
}


思路二:

如果无0且负数的个数为偶数,则将数组中所有数相乘即可;
如果无0且负数的个数为奇数,则定位最左边和最右边的负数的下标(pos1,pos2),然后将pos2左边的数全部相乘得到result1(不包括pos2),同理将pos1右边的数相乘得到result2,然后比较result1和result2即可;
如果出现0(一个或者多个),则将0作为分界点,分别使用上述两个步骤求出最大值,然后在比较各个最大值即可。

时间复杂度:O(n)

int GetMax(int a[], const int &length)
{
int zeros=0,nega=0,negaPos[2];
int i=0;
vector<int> flagZeros;
for(i=0; i<length; i++)
{
if(a[i]==0)
{
zeros++;
flagZeros.push_back(i);
}
else if(a[i]<0)
{
nega++;
if(nega==1)   //只有一个元素
{
negaPos[0] = i;
negaPos[1] = i ;
}
else
negaPos[1] = i ;
}
}
if((zeros==0) && (nega%2==0))
{
int result = a[0];
for(i=1; i<length; i++)
result *= a[i];
return result;
}
else if( zeros==0 && (nega%2==1) )
{
int result[2]={a[0],a[negaPos[0]+1]};
for(i=1;i<negaPos[1];i++)
result[0] *= a[i];
for(i=negaPos[0]+2;i<length;i++)
result[1] *= a[i];
return result[0]>result[1]?result[0]:result[1];
}
else
{
vector<int> temp;
int j=0;
int *b = new int[length];
vector<int>::iterator iter = flagZeros.begin();
for( ; iter!=flagZeros.end(); iter++)
{
for(i=0; j<length && i<*iter; i++)
b[i]=a[j++];
j++;  //下一段
//cout<<GetMax(b,i)<<endl;
temp.push_back(GetMax(b,i));
}
for(i=0; j<length; i++)  //0的最后一部分
b[i]=a[j++];
//cout<<GetMax(b,i)<<endl;
temp.push_back(GetMax(b,i));

delete [] b;
return *max_element(temp.begin(), temp.end());
}
}

int main()
{
//int a[] = {1,-2,-3,-5,7,8};    //840
<span style="white-space:pre">	</span>//int a[] = {1,-2,-3,0,-5,7,8};   //56
//int a[] = {1,-2,-3,0,-5,-7,8};  // 280
cout<<GetMax(a, sizeof(a)/ sizeof(int))<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: