目录:
1、问题以及问题分析
2、解决方案
2.1 方法一
2.2 方法二
3、其他
1、问题以及问题分析
题目来自:leetcode
网址:https://oj.leetcode.com/problems/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
.
这里只用求最大的输出,而不用求出最大输出的数组。
提示:在leetcode提交框中有示例的程序框架,其中的返回值为int,可以知道本体中的都都是int类型,而不存在小数类型。
那么现在问题中的元素可以分为三类,分为:正数、负数、零。那么这样就而已进行如下的编程了。
2、解决方案
2.1 方法一
直接用遍历所有的数组元素,找出其中最大值
只要注意一点便可,其中负数和负数相乘会变为正数(这有点太弱智了),但是需要记住,所以在保存最大值的同时,我们还需要保存最小值,因为乘以一个赋值,最大最小值的地位将会发生变化,代码如下:
public class MaximumProductSubarray { public int maxProduct(int[] A) { int max,min; //定义最大最小值 int maxTmp,minTmp; //定义最大最小值的暂存 int maxProduct = Integer.MIN_VALUE;//给输出赋初值,给最小值 max = min = 1; //赋初值 for(int i=0; i<A.length; i++){ maxTmp = Math.max(Math.max(max*A[i],min*A[i]),A[i]); //如果出现选择为A[i]那么代表,不延续原先的子序列了 minTmp = Math.min(Math.min(max*A[i],min*A[i]),A[i]); max = maxTmp; //保存值 min = minTmp; maxProduct = Math.max(max,maxProduct); //找寻最大值 } return maxProduct; } public static void main(String[] args) { //main int A[] = {-4,-3,-2}; MaximumProductSubarray m = new MaximumProductSubarray(); System.out.println(m.maxProduct(A)); } }
2.2 方法二
分析:
- 由于是int型,所以不存在绝对值缩小的情况
- 如果都是正数,那么就是把所有的项相乘就是
- 如果存在负数,如果是偶数个,那么所有的数相乘并是;如果是奇数个,若从左边开始最大输出为到最后一个奇数的所有的项的乘积,若从右边开始到最后一个奇数前的所有的项之积就是最大的输出。(所以程序中分别从左右两边开始)
- 如果存在零,那么就是把数组分割为几个子数组进行处理。 (换句话说,原先的积累清零,从新开始寻找最大最小值)
class Solution { public: int maxProduct(int A[], int n) { int b=1, f=1, res=INT_MIN; for(int i=0; i<n; i++){ res=max(res, max(b*=A[i],f*=A[n-1-i])); //程序分别从左右开始遍历 if(b==0) b=1; //若遇到零,遍历从零之后的项开始 if(f==0) f=1; } return res; } };
3、其他
针对方法一,有一种更省代码的写法,如下:
int maxProduct(int A[], int n) {//可以认为对方最先的方法一的一种改善 if(n==1) return A[0]; int pMax=0, nMax=0, m = 0; for(int i=0; i<n; i++){ if(A[i]<0) swap(pMax, nMax);// //在和小于零的数相乘后,最大最小值将会转换,这里先进行转换 pMax = max(pMax*A[i], A[i]); nMax = min(nMax*A[i], A[i]); m = max(m, pMax); } return m; }