Maximum Product Subarray

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.

即求连续的子数组乘积最大的值,该问题同求解连续子数组和最大的值具有相似性,都可以通过动态规划求解。

连续子数组和最大分析

对于a[i],当前最大值分为三种情况:

case 1:即a[i]即构成子数组和最大;

case 2:a[i]同sum[i-1]构成连续的子数组且和最大,即为sum[i-1]+a[i];

case 3:a[i]不构成连续的子数组,即sum[i-1]为a[0,……i]中连续子数组的最大和

因此,根据上述三种情况,不难知道其状态方程为:sum[i] = max(sum[i-1],a[i],a[i]+sum[i-1])

	/**
	 * 求解a[0],……,a[n-1]连续子数组和且最大
	 * @param datas
	 * @return
	 */
	public int findNegativeMaxSubArraySum(int[] datas) {
<span style="white-space:pre">		</span>int sum = array[0];
<span style="white-space:pre">		</span>for(int i = 1; i < array.length; i++){
<span style="white-space:pre">			</span>sum = max(max(array[i],array[i]+sum),sum);
<span style="white-space:pre">		</span>}
<span style="white-space:pre">		</span>return sum;
	}


连续子数组乘积最大分析

对于乘积,情况就有点点不相同,其状态方程并不是product[i] = max(product[i-1],a[i],a[i]*product[i-1])。

对于[-2,-3,-4],其连续的最大乘积为12,但是若按照刚刚提到了状态方程,其结果为6。之所以会这样,是因为那个状态方程没有考虑到负负得正的情况。因此,不仅要维护当前的最大值,还要维护一个最小值。

  tmp = start;

start= max(max(start * A[i], A[i]), min_local * A[i]);

                        min_local = min(min(tmp * A[i], A[i]),min_local*A[i]);

product = max(start, product);
LeetCode的证明:

Let us denote that:

f(k) = Largest product subarray, from index 0 up to k.

Similarly,

g(k) = Smallest product subarray, from index 0 up to k.

Then,

f(k) = max( f(k-1) * A[k], A[k], g(k-1) * A[k] )
g(k) = min( g(k-1) * A[k], A[k], f(k-1) * A[k] )
	public int solution(int[] A) {
		int start = A[A.length - 1];
		int product = A[A.length - 1];
		int min_local = A[A.length - 1];
		for (int i = A.length - 2; i >= 0; i--) {
			int tmp = start;
			start = max(max(start * A[i], A[i]), min_local * A[i]);
			min_local = min(min(tmp * A[i], A[i]),min_local*A[i]);
			product = max(start, product);
		}
		return product;
	}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值