最大子序和及乘积最大子数组

题目链接:

最大子序和: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;
    }
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值