152. 乘积最大子数组 动态规划

该博客讨论了如何使用动态规划方法解决152题——乘积最大子数组的问题。通过记录最大和最小累计乘积,在遍历过程中处理负数的情况,确保能够找到最大乘积。同时提到了另一种从左往右和从右往左遍历两次的解题思路。
摘要由CSDN通过智能技术生成

152. 乘积最大子数组

难度:中等 2020/5/18每日一题打卡√
今天也是磨磨蹭蹭只想完成任务的一天
题目描述
在这里插入图片描述
解题思路
参考题解:动态规划(理解无后效性)

1、记录最大最小累计和

这道题和最大子序和那道好像,也是用动态规划,但是比那个要复杂一点。
首先因为数字都是整数,所以如果乘一个正数肯定会使结果增大,乘一个负数会让结果减小。问题在于负数的个数不确定,如果时偶数个负数的话,那整个数组所有的元素累乘就是最后结果,如果负数个数是奇数个就不能这样。
所以在遍历计算最大值的时候,也要顺便把最小值记录下来,因为如果乘一个负数,最大值就会变成最小值,最小值就会变成最大值

/*
	  * 152. 乘积最大子数组
	  * 2020/5/18 每日一题
	  */
	 public static int maxProduct(int[] nums) {
		 int max = 1,min = 1,re = Integer.MIN_VALUE;
		 for (int i = 0; i < nums.length; i++) {  //依次找到乘积最大值
			 if(nums[i] < 0) {  //如果要乘的数小于0
					int temp = max;
					max = min;
					min = temp;
				}
			max = Math.max(max*nums[i], nums[i]);
			min = Math.min(min*nums[i], nums[i]);
			re = Math.max(re, max);
			//System.out.println(max+" "+min+" "+re);
		}		 
		 return re;
	    }

在这里插入图片描述
这个方法是看评论的,当时觉得有点难理解,看看运行过程之后好懂一点。
样例:2,3,-2,4,-1,8,0,23,-1,56,0,0,0
过程:
2 2 2
6 3 6
-2 -12 6 //反转
4 -48 6
48 -4 48 //反转
384 -32 384
0 0 384
23 0 384
0 -23 384
56 -1288 384
0 0 384
0 0 384
0 0 384
记录最小值的作用在于遇到负数的时候能正确的得到负数或者负负得正
如果没有这个的话,是这样,遇到负数就会丢掉一部分结果
2 2
6 6
-2 6
4 6
-1 6
8 8
0 8
23 23
-1 23
56 56
0 56
0 56
0 56

2、从左往右和从右往左遍历两次

也是一种有点神奇的方法,不知道他们怎么想到的
还是分情况:(先假设数组里不存在0)
如(1,-2,3,-4,5)
1、负数个数是偶数,比较简单,如果是这样那从左往右遍历的时候就能找到最大值
在这里插入图片描述
2、负数个数是奇数,从左往右就得不到正确答案,那从右往左再开始一次
1,-2,-3,-4,5
在这里插入图片描述
奇数个数的负数,要么不要最左边那个负数,要么不要最右边那个负数,比较两种那种最大

public int maxProduct(int[] nums) {
        int max = Integer.MIN_VALUE,sum = 1;
		 for (int i = 0; i < nums.length; i++) {  //从左边开始
			 sum = sum*nums[i];
			 max = Math.max(max, sum);
			 if(nums[i] == 0)  //如果遇到1,重新开始
				 sum = 1;
		}
		 sum = 1;
		 for (int i = nums.length-1; i > 0; i--) {
			 sum = sum*nums[i];
			 max = Math.max(max, sum);
			 if(nums[i] == 0)  //如果遇到1,重新开始
				 sum = 1;
		}
		 
		 return max;
    }

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值