题目链接:
最大子序和:https://leetcode-cn.com/problems/maximum-subarray/
乘积最大子数组:https://leetcode-cn.com/problems/maximum-product-subarray/
解题思路:
动态规划问题要满足三个条件,第一是最优子结构,第二是子问题重叠,第三是无后效性。最难的是找到状态转移方程。
两个题目的状态转移方程的关键点在于理解以第i个元素结尾的最大值。
举例说明:
测试数组为[1,7,-3,4]
以index=0即元素1结尾的子序列中和最大的为1(因为以1结尾的子序列仅有一个是[1])
以index=1即元素7结尾的子序列中和最大的是多少呢?以元素7结尾,则子序列一定包含7,最大值可能来自两个子序列
1、若要和其前面的元素连续起来组成子序列,则子序列中一定包含其前一个元素即1,而以index=i-1结尾的最大和我们已经求出来了,是max[i-1], 所以max[i]=max[i-1]+nums[i];
2、也有可能不与前面元素组成子序列,元素本身自己成为子序列,则max[i]=nums[i];
因此,max[i]=MAX(max[i-1]+nums[i],nums[i]);
class Solution {
public int maxSubArray(int[] nums) {
int ans = nums[0];
int sum = 0;
for(int num: nums) {
sum = Math.max(sum+num, num);
ans = Math.max(ans, sum);
}
return ans;
}
}
class Solution {
public int maxProduct(int[] nums) {
int len = nums.length;
if(len == 0){
return 0;
}
int res = Integer.MIN_VALUE;
int max_i = 1;
int min_i = 1;
for(int i = 0 ; i < len; i++){
if(nums[i] < 0){
int temp = max_i;
max_i = min_i;
min_i = temp;
}
max_i = Math.max(max_i*nums[i], nums[i]);
min_i = Math.min(min_i*nums[i], nums[i]);
res = Math.max(max_i, res);
}
return res;
}
}