其他分享
首页 > 其他分享> > 283,乘积最大子序列

283,乘积最大子序列

作者:互联网

给定一个整数数组 nums ,找出一个序列中乘积最大的连续子序列(该序列至少包含一个数)。

示例 1:

输入: [2,3,-2,4]
输出:6
解释: 子数组 [2,3] 有最大乘积 6。

示例 2:

输入: [-2,0,-1]
输出: 0
解释: 结果不能为 2, 因为 [-2,-1] 不是子数组。

答案:

 1int maxProduct(int A[]) {
2    int r = A[0];
3    for (int i = 1, max = r, min = r; i < A.length; i++) {
4        if (A[i] < 0) {//交换max和min
5            max ^= min;
6            min ^= max;
7            max ^= min;
8        }
9        max = Math.max(A[i], max * A[i]);
10        min = Math.min(A[i], min * A[i]);
11        r = Math.max(r, max);
12    }
13    return r;
14}

解析:

求最大乘积,如果A[i]<0,那么就交换max和min的值,因为如果一个数是负数,那么他乘以一个较大的数结果会更小。我们还可以先不判断A[i]的值,先相乘,再比较

 1public int maxProduct(int[] A) {
2    if (A == null || A.length == 0) {
3        return 0;
4    }
5    int max = A[0], min = A[0], result = A[0];
6    for (int i = 1; i < A.length; i++) {
7        int temp = max;
8        max = Math.max(Math.max(max * A[i], min * A[i]), A[i]);
9        min = Math.min(Math.min(temp * A[i], min * A[i]), A[i]);
10        if (max > result) {
11            result = max;
12        }
13    }
14    return result;
15}

下面再来看种写法

 1public int maxProduct(int A[]) {
2    int frontProduct = 1;
3    int backProduct = 1;
4    int ans = Integer.MIN_VALUE;
5    for (int i = 0; i < A.length; ++i) {
6        frontProduct *= A[i];
7        backProduct *= A[A.length - i - 1];
8        ans = Math.max(ans, Math.max(frontProduct, backProduct));
9        frontProduct = frontProduct == 0 ? 1 : frontProduct;
10        backProduct = backProduct == 0 ? 1 : backProduct;
11    }
12    return ans;
13}

一个从前面开始计算,一个从后面开始计算。还可以在改一下

 1public int maxProduct(int[] nums) {
2    int max = Integer.MIN_VALUE, product = 1;
3    int len = nums.length;
4    for (int i = 0; i < len; i++) {
5        max = Math.max(product *= nums[i], max);
6        if (nums[i] == 0) product = 1;
7    }
8    product = 1;
9    for (int i = len - 1; i >= 0; i--) {
10        max = Math.max(product *= nums[i], max);
11        if (nums[i] == 0) product = 1;
12    }
13    return max;
14}

上面两种解法的原理其实都是一样的,假如没有0的情况下,如果负数的个数是偶数,那么无论从前往后还是从后往前都能求出最终结果,且结果都是一样的,只需要把所有的数相乘即可。如果负数的个数是奇数,那么最后一个负数我们是不能相乘的,所以会有两种情况,一种是最前面的负数之前的不要乘,一种是最后面负数之后的不要乘。如果有0的情况下,遇到0我们只需要把product重置为1即可。相当于以0为分界点把数组分为两部分。后面部分会再次重复上面的步骤……

标签:product,乘积,min,int,max,nums,序列,283,Math
来源: https://blog.51cto.com/u_4774266/2902492