LeetCode T152.Maximum Product Array/乘积最大子数组——动态规划

在本题中,若我们从前往后遍历数组,那么此后满足要求的解的每一个状态都等于max{state[i-1]*nums[i], nums[i]},这就构成了一个状态转移的关系,但同时由于乘法负负得正的特殊性,因此我们除了记录正值的最大值,同时也需要记录负值的最小值,即有两组状态转移方程:

1. maxF[i]=max{maxF[i-1]*nums[i], minF[i-1]*nums[i], nums[i]};

2. minF[i]=min{maxF[i-1]*nums[i], minF[i-1]*nums[i], nums[i]};

之后,可以看到在所有的表达式中,我们只需要记录maxF[i-1], minF[i-1]即可,因此我们可以优化用临时变量替代state[i-1],即:

1. maxF=minF=ans=nums[0];

//开始循环

  2. mx=maxF, mn=minF;

  3. maxF=max{mx*nums[i], mn*nums[i], nums[i]};

  4. minF=min{mx*nums[i], mn*nums[i], nums[i]};

  5. ans=max{ans, maxF};

return ans

时间复杂度为O(n),空间复杂度为O(1);

我的题解大妈如下,leetcode上运行用时4ms,内存占用5.9MB

int max(int a,int b,int c){
    if(a>b){
        if(b>c) return a;
        else if(c>a) return c;
        else return a;
    }
    else{
        if(a>c) return b;
        else if(c>b) return c;
        else return b;
    }
}

int min(int a,int b,int c){
    if(a<b){
        if(b<c) return a;
        else if(c<a) return c;
        else return a;
    }
    else{
        if(a<c) return b;
        else if(c<b) return c;
        else return b;
    }
}

int maxProduct(int* nums, int numsSize){
    int maxF=nums[0],minF=nums[0],ans=nums[0];
    for(int i=1;i<numsSize;i++){
        int mx=maxF, mn=minF;
        maxF=max(mx*nums[i],mn*nums[i],nums[i]);
        minF=min(mx*nums[i],mn*nums[i],nums[i]);
        ans=maxF>ans?maxF:ans;
    }
    return ans;
}

猜你喜欢

转载自www.cnblogs.com/runsdeep/p/12908494.html