LeetCode 53 最大子数组和 - 动态规划解法

LeetCode 53 最大子数组和 - 动态规划解法

https://leetcode.cn/problems/maximum-subarray/description/

思路

暴力穷举

class Solution {

public:

    int maxSubArray(vector<int>& nums) {

        int res=INT_MIN;

        for(int index =0;index<nums.size();index++){

            for(int len = 0;len+index<nums.size();len++){

                int sum = 0;

                for(int j = index;j<=index+len;j++){

                    sum+=nums[j];

                }

                res = max(sum,res);

            }

        }

        return res;

     }

};

动规

第一次做这题时,动规思路并不清晰。复盘后可以这样理解:

这题的答案不是 dp 数组最后一个位置的值,而是从所有状态中按规则(这里取最大值)选出来。因此,dp 数组(或递归函数)的语义本质是“状态分类”,关键是怎么分。

这里的分类方式是:以 index 开头的子数组最大和。不同 index 之间存在递推关系,所以可以使用递归/动态规划。

穷举所有情况->分类->加上最优性质->各个类别之间产生关系。

递归

class Solution {

public:

    int res = INT_MIN;

    int get_max(vector<int> nums,int index){

        if(index==nums.size()) return 0;

        int tmp = get_max(nums,index+1);

        if(tmp<0){

            res = max(res,nums[index]);

            return nums[index];

        }else{

            res = max(res,nums[index]+tmp);

            return nums[index]+tmp;

        }

    }

    int maxSubArray(vector<int>& nums) {

        get_max(nums,0);

        return res;

    }

};

动规

class Solution {

public:

    int maxSubArray(vector<int>& nums) {

        int max_value = INT_MIN;

        vector<int> re_value = vector<int>(nums.size()+1,INT_MIN);

        re_value[nums.size()] = 0;

        for(int i = nums.size()-1;i>=0;i--){

            re_value[i+1]>0?re_value[i] = nums[i]+re_value[i+1]:re_value[i] = nums[i];

            max_value = max(max_value,re_value[i]);

        }

        return max_value;

    }

};

发现for循环内 只依赖 i+1 ,因此可以只维护一个变量:last。

class Solution {

public:

    int maxSubArray(vector<int>& nums) {

        int max_value = INT_MIN;

        int last =0;

        for(int i = nums.size()-1;i>=0;i--){

            last>0?last = nums[i]+last:last = nums[i];

            max_value = max(max_value,last);

        }

        return max_value;

    }

};