LeetCode/最大子数组和

给你一个整数数组nums,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
子数组是数组中的一个连续部分。

1. 暴力法(超时)

三重循环(列所有数组)
class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int n=nums.size();
        int max_=nums[0];
        int temp;
        for(int len=1;len<=n;len++){
            for(int i=0;i<=n-len;i++){
                temp =0;
                for(int j=i;j<i+len;j++){
                    temp=temp+nums[j];
                }
                max_=max(max_,temp);
            }
        }
        return max_;
    }
};

从前往后遍历过程的一次过程中,相当于每一趟比较了所有以i开头的连续数组的最大和,
把所有开头的连续数组比较完即可,时间复杂度为O(n2)
其实可以从后往前遍历,相当于写成每一趟比较以i结尾的连续数组

二重循环
class Solution
{
public:
    int maxSubArray(vector<int> &nums)
    {
        //类似寻找最大最小值的题目,初始值一定要定义成理论上的最小最大值
        int max = INT_MIN;
        int numsSize = int(nums.size());
        for (int i = 0; i < numsSize; i++)
        {
            int sum = 0;
            for (int j = i; j < numsSize; j++)
            {
                sum += nums[j];
                if (sum > max)
                {
                    max = sum;
                }
            }
        }

        return max;
    }
};

2. 动态规划

数组没有方向,所以从前往后和从后往前缩小问题规模,没有什么差别
那么要如何缩小问题规模呢?
假定从前往后的话,要使得评估长度i和i+1数组的方程产生联系
注意到题目中的连续数组,所以可以设dp[i]表示为以nums[i]结尾的连续子数组最大和
这样我们既能完成状态的转移,又能对所有数组进行有效的评估
状态转移方程为dp[i]=max(nums[i],dp[i-1]+nums[i])
边界条件:dp[0]=nums[0]

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int n=nums.size();
        int max_=INT_MIN;
        vector<int> dp(n);
        dp[0]=nums[0];
        for(int i=1;i<n;i++)
            dp[i]=max(nums[i],dp[i-1]+nums[i]);
        for(int i=0;i<n;i++)  
            max_=max(max_,dp[i]);
        return max_;
    }
};
滚动变量空间优化
class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int max_=INT_MIN;
        int dp;
        max_=dp=nums[0];
        for(int i=1;i<nums.size();i++){
            dp=max(nums[i],dp+nums[i]);
            max_=max(max_,dp);
        }
        return max_;
    }
};

同样可以从后往前遍历,状态设dp[i]表示为以nums[i]开头的连续子数组最大和
状态转移方程为dp[i]=max(nums[i],dp[i+1]+nums[i])
边界条件:dp[0]=nums[n-1]

posted @ 2022-05-18 21:07  失控D大白兔  阅读(42)  评论(0)    收藏  举报