Find the contiguous subarray within an array (containing at least one number) which has the largest product.
For example, given the array [2,3,-2,4]
,
the contiguous subarray [2,3]
has the largest product = 6
.
题目分析:
之前,做过maxsum,就想用类似的思路去解决这道题,遍历求局部最大值,然后与之前的最大值相比较。
不过最大乘积相比与最大和麻烦的地方在于对负数以及0的处理。
最大乘积有正有负,所以我们设置两个变量分别存储正向最大和负向最大
首先是对0的处理,碰到0,正向最大和负向最大都要回到初始值,并且更新最大值。
其次是正数的处理,更新正向最大,如果已经有负值,更新负向最大,并且更新最大值。
最后是对负数的处理,如果第一次出现负数,更新负数最大,正数最大为初始值,否则,正数最大为负数最大*当前值,负数最大为正数最大*当前值,注意:一定要设临时变量
代码如下:
public class MaximumProductSubarray {
public int maxProduct(int[] nums) {
int posMax=1;
int negMax=1;
int len =nums.length;
if(len<1) return 0;
int max=nums[0];
for(int i=0;i<len;i++)
{
int tmp=nums[i];
if(tmp==0)
{
if(posMax>max&&posMax!=1) max=posMax;
posMax=1;
negMax=1;
if(max<0) max=0;
}
if(tmp>0)
{
posMax*=tmp;
if(negMax<0) negMax*=tmp;
if(posMax>max) max=posMax;
}
if(tmp<0)
{
if(negMax==1)
{
if(posMax>max&&posMax!=1) max=posMax;
negMax=posMax*tmp;
posMax=1;
}
else
{
int bef=posMax;
posMax=negMax*tmp;
negMax=bef*tmp;
if(posMax>max) max=posMax;
}
}
}
return max;
}
@Test
public void case1()
{
int[] nums={2,3,-2,4};
int result=maxProduct(nums);
int actual=6;
Assert.assertEquals("not equal", result, actual);
}
@Test
public void case2()
{
int[] nums={2,3,-2,4,-3};
int result=maxProduct(nums);
int actual=144;
Assert.assertEquals("not equal", result, actual);
}
@Test
public void case3()
{
int[] nums={2,0,-2,4,-3};
int result=maxProduct(nums);
int actual=24;
Assert.assertEquals("not equal", result, actual);
}
@Test
public void case4()
{
int[] nums={-3};
int result=maxProduct(nums);
int actual=-3;
Assert.assertEquals("not equal", result, actual);
}
@Test
public void case5()
{
int[] nums={-3,-4,-5};
int result=maxProduct(nums);
int actual=20;
Assert.assertEquals("not equal", result, actual);
}
@Test
public void case6()
{
int[] nums={2,3};
int result=maxProduct(nums);
int actual=6;
Assert.assertEquals("not equal", result, actual);
}
@Test
public void case7()
{
int[] nums={-2,0,-1};
int result=maxProduct(nums);
int actual=0;
Assert.assertEquals("not equal", result, actual);
}
}
可以用junittest来检测代码的正确性。
这个问题并不难,主要是细节的处理。
进阶篇为浮点数的最大乘积,这时候要考虑最大正值最大负值跟1的关系,且听下回分解