给定一个整数数组 nums ,找出一个序列中乘积最大的连续子序列(该序列至少包含一个数)。
思路:
即使是我这种动态规划菜鸡也能一眼看出这是一道动态规划题目。
所以用到dp[i] = max(nums[i],dp[i-1]*nums[i])。不过不同的是这个题中的数可能是负数,所以,最大的很有可能变最小的,最小的也有可能变最大的。所以需要两个dp,分别是dp_max[]和dp_min[]。当是负数时就用前一个最小乘积乘当前数字来求最大乘积。
- 时间复杂度:O(n),遍历数组。
- 空间复杂度:O(n),建立了两个新数组,占用空间和nums长度呈线性关系。
class Solution {
public int maxProduct(int[] nums) {
int length = nums.length;
if(length==0) return 0;
int[] dp_max = new int[length];
int[] dp_min = new int[length];
dp_max[0] = nums[0];
dp_min[0] = nums[0];
for(int i=1;i<length;i++){
if(nums[i]>0){
dp_max[i] = dp_max[i-1]*nums[i]>nums[i]?dp_max[i-1]*nums[i]:nums[i];
dp_min[i] = dp_min[i-1]*nums[i]<nums[i]?dp_min[i-1]*nums[i]:nums[i];
}else{
dp_max[i] = dp_min[i-1]*nums[i]>nums[i]?dp_min[i-1]*nums[i]:nums[i];
dp_min[i] = dp_max[i-1]*nums[i]<nums[i]?dp_max[i-1]*nums[i]:nums[i];
}
}
int max = dp_max[0];
for(int m:dp_max){
if(m>max) max=m;
}
return max;
}
}