题目如下:
第一次做这个题的时候想到的是暴力法,暴力法就直接用双重循环,依次遍历数组,然后挨个比较大小。
然后又想到了双指针法,可是这道题目貌似双指针法和暴击解法没啥太大的差别。
所以这样一想就放弃了,然后看了一下优秀的题解方法,在题解方法中大多数使用的都是动态规划思想,可是我看了半天还是不是很理解他们的那种动态规划算法思想。这是官方C++思路。
它的动态规划转移方程为:
动态规划的思想是当前状态可以由上一个状态得到,可是我的想法是题目不是要求乘积最大的连续子数组嘛,这样的转移方程能求出当前数到它前面的数的乘积最大的连续子数组嘛,然后反反复复想了很久还是有些不能接受,直到昨天晚上睡觉的时候相通了,由于它每一步都是用前面的最大和最小值乘以当前元素,所以可以保证是连续子数组相乘。
想通了以后今天早上就自己开始写了。
class Solution {
//动态规划问题
public int maxProduct(int[] nums) {
//首先判断数组是否为空,如果为空则返回0
if(nums.length == 0) return 0;
//定义两个状态转移数组,存储每一步得到的连续乘积最大和最小的值,由于数组中可能出现负数,因为负负得正,所以不仅得建立最大状态数组还得建立最小状态数组。
int[] max = new int[nums.length];
int[] min = new int[nums.length];
//第一M存储最大乘积
int M = nums[0];
max[0] = M;
min[0] = M;
for(int i=1;i<nums.length;i++){
//用前一步最大值乘以当前数,当前数,前一步最小值乘以当前数,取三个数的最大值作为状态转移数组的最大值。
max[i] = Math.max(max[i-1]*nums[i],Math.max(nums[i],min[i-1]*nums[i]));
min[i] = Math.min(max[i-1]*nums[i],Math.min(nums[i],min[i-1]*nums[i]));
M = Math.max(M,max[i]);
}
return M;
}
}