子数组的最大乘积

转载地址:http://blog.csdn.net/ns_code/article/details/29224185

    给定一个长度为N的整数数组,只允许使用乘法,不能使用除法,计算任意N-1个数的组合乘积的最大值。


    这道题目重点要注意数组中有负数、0的情况。最直观的做法就是把所有可能的N-1个数的组合找出来,分别计算他们的乘积,并比较大小。找出所有组合需要O(N)时间,计算每个组合的乘积需要O(N)时间,因此该算法的时间复杂度为O(N*N)。

    编程之美上给出了两种O(N)的解法。

    第一种比较直观,假设去掉第i个元素后的剩下的N-1个元素的成绩为p[i],则从左向右扫描数组,计算第0到第i-1个元素的乘积s[i],再从右向左扫描数组,计算从第N-1个元素到第i+1个元素的乘积t[i],二者相乘便是除去第i个元素的剩下N-1个元素的乘积p[i],而后比较所有的p[i]即可。由于每次计算s[i+1]和t[i-1]时直接可以利用s[i]和t[i]的结果,因此扫描一次过去的时间复杂度为O(N),找出p[i]的最大值也是O(N),因此时间复杂度为O(N)。

    第二种方法,将问题转化到对去掉的那个元素的分析上,只在最后计算一次乘积即可。这种方法要先扫描一次数组,得到数组中正整数的个数、负整数的个数、0的个数,最小的正整数、绝对值最大的负整数和绝对值最小的负整数。而后详细地根据数组中正负数以及0的个数来判断要剔除的元素。

    1、如果数组中0的个数大于1,则任意N-1个元素的乘积都为0,去掉任一元素均可;

    2、如果数组中0的个数为1,则需要分两种情况;

    {

1、如果数组中负数的个数为偶数个,此时去掉0,剩下的N-1个数的乘积最大,为正值;

2、如果数组中负数的个数为奇数个,此时N-1个数的乘积最大值为0,去掉任意一个非0元素即可。

    }    

    3、如果数组中没有0,则需要分两种情况:

    {

1、如果数组中的负数个数为奇数个,此时去掉一个负数后的剩下N-1个数的乘积为正值,要保证这个正值最大,我们需要去掉绝对值最小的负            数,即最大的负数;

     2、如果数组中的负数个数为偶数个,则需要分两种情况:

     {

    1、如果数组中没有正整数,则去掉一个负数后,剩下的N-1个数的乘积为负值,要保证这个负值最大,我们需要去掉绝对值大的负数 ,                即最小的负数;

         2、如果数组中有正整数,则去掉最小的正整数,剩下的N-1个元素的乘积即为最大的。

}

    }

点赞