※ Leetcode - Dynamic Programming - 53.Maximum Subarray(最大连续和)+152.Maximum Product Subarray(最大连续积)

1. Problem Description of 53.Maximum Subarray

Find the contiguous subarray within an array (containing at least one number) which has the largest sum.

 

For example, given the array [2,1,3,4,1,2,1,5,4],

the contiguous subarray [4,1,2,1] has the largest sum = 6.

求一个数组的最大连续和

 

2. My solution

这类问题需要关注的核心问题是:

 

局部最优解如何求得,和全局最优解的关系(状态转移方程的确定)

 

该题的状态转移方程,仅考虑两个值得大小:Local[i-1]+nums[i]nums[i]

因此:Local[i]=max([i-1]+nums[i],nums[i])

  int maxSubArray(vector<int>& nums)
    {
        vector<int>local;
        int len=nums.size();
        //range of int:-(1<<31)~(1<<31)-1
        
        if(len==1)
            return nums[0];
        local.push_back(nums[0]);
        int global=local[0];
        for(int i=1; i<len; i++)
        {
           local.push_back(max(local[i-1]+nums[i],nums[i]));
           global=max(global,local[i]);
        }
        return global;
    }

3. Problem Description of 152. Maximum Product Subarray

Find the contiguous subarray within an array (containing at least one number) which has the largest product.

 

For example, given the array [2,3,-2,4],

the contiguous subarray [2,3] has the largest product = 6.

求数组中元素的最大连续积。

4. My solution

题目与最大连续和的区别关键在于我们不能只考虑前一个最大数与当前数的和。

因为负数的存在,很可能一个绝对值较大的负数,和一个负数相乘得到一个很大的证书。

所以除了记录局部最大值,我们还应该记录局部最小值。

因为nums[i]的正负未知,我们直接把前一个局部最大值和局部最小值分别与nums[i]相乘。

得到:

 int tmin=minlocal[i-1]*nums[i];

 int tmax=maxlocal[i-1]*nums[i];

最后当前的局部最大值和局部最小值,通过比较三个数得到:

Tmin,tmax,nums[i]

然后更新global值就可以啦~


  int maxProduct(vector<int>& nums)
    {
        int len=nums.size();
        if(len==1)
            return nums[0];
        vector<int>minlocal;
        vector<int>maxlocal;
 
        minlocal.push_back(nums[0]);
        maxlocal.push_back(nums[0]);
        int global=nums[0];
 
        for(int i=1; i<len; i++)
        {
            int tmin=minlocal[i-1]*nums[i];
            int tmax=maxlocal[i-1]*nums[i];
            minlocal.push_back(min(min(tmin,tmax),nums[i]));
            maxlocal.push_back(max(max(tmin,tmax),nums[i]));
            global=max(maxlocal[i],global);
        }
        return global;
    }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值