leetcode 53. Maximum Subarray 动态规划DP + 最大子串和

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.

这道题就是经典的最大子串和的问题,使用循环或者优化过后的循环肯定会超时,这个题最好采用DP,主要参考这个链接:DP动态规划——最大数字子串

注意要考虑到全是负数的情况,分情况讨论即可

设计一个输入数组a[i],用数组dp[i]记录最后一个数为a[i]时的最大子串和,状态转移方程为 :
dp[i] = max(dp[i-1]+a[i],a[i]);
初始条件dp[0]=a[0], 然后dp[i]中最大元素即为所求。

当然也可以使用一个变量来表示最大值,而不是建立一个dp数组,这个参见第二个解决方法。

代码如下:

public class Solution
{
    /*
     * 输入数组a[i],用数组dp[i]记录最后一个数为a[i]时的最大子串和
     * 状态转移方程为 : dp[i] = max(dp[i-1]+a[i],a[i]); 1<=i<n-1  
     * 初始条件dp[0]=a[0]
     * 然后dp[i]中最大元素即为所求。 
     * */
    public int maxSubArray(int[] nums) 
    {
        if(nums==null || nums.length<=0)
            return 0;

        int []dp=new int[nums.length];
        dp[0]=nums[0];
        for(int i=1;i<nums.length;i++)
        {
            dp[i]=Math.max(dp[i-1]+nums[i], nums[i]);
/*          if(dp[i-1]<0)
                dp[i]=nums[i];
            else 
                dp[i]=dp[i-1]+nums[i];*/
        }

        int maxSum=dp[0];
        for(int i=0;i<dp.length;i++)
            maxSum=Math.max(maxSum, dp[i]);

        return maxSum;
    }

    public int maxSubArrayWithO1(int[] nums) 
    {
        if(nums==null || nums.length<=0)
            return 0;

        //最大子串问题
        int len=nums.length;
        int sum=Integer.MIN_VALUE;

        //DP解决  ,一定要记着
        int dp=0;
        for(int i=0;i<len;i++)
        {
            if(dp>0)
                dp+=nums[i];
            else 
                dp=nums[i];
            sum=Math.max(sum, dp);
        }

        return sum;
    }

    /*
     * 通过最直接的循环来做
     * 
     * */
    public int maxSubArrayByLoop(int[] nums) 
    {
        if(nums==null || nums.length<=0)
            return 0;

        //最大子串问题
        int len=nums.length;
        int sum=Integer.MIN_VALUE;

        /*//循环解决,肯定会超时
        for(int i=0;i<len;i++)
        {
            for(int j=i;j<len;j++)
            {
                int tt=0;
                for(int k=i;k<=j;k++)
                {
                    tt+=nums[k];
                }
                sum=(tt >= sum)? tt : sum;
            }
        }*/

        //优化方案,但是也极有可能超时
        for(int i=0;i<len;i++)
        {
            int tt=0;
            for(int j=i;j<len;j++)
            {
                tt+=nums[j];
                sum=(tt >= sum)? tt : sum;
            }
        }

        return sum;
    }
}

下面是C++的动态规划做法,很简单,也很经典,必须要记住

代码如下:

#include <iostream>
#include <vector>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <queue>
#include <stack>
#include <string>
#include <climits>
#include <algorithm>
#include <sstream>
#include <functional>
#include <bitset>
#include <numeric>
#include <cmath>
#include <regex>
#include <iomanip>
#include <cstdlib>
#include <ctime>

using namespace std;



class Solution 
{
public:
    int maxSubArray(vector<int>& a)
    {
        if (a.size() <= 0)
            return 0;
        int res = INT_MIN, dp = 0;
        for (int i = 0; i < a.size(); i++)
        {
            if (dp > 0)
                dp += a[i];
            else
                dp = a[i];
            res = max(res, dp);
        }
        return res;
    }

    int maxSubArrayByDP(vector<int>& a) 
    {
        if (a.size() <= 0)
            return 0;
        vector<int> dp(a.size(), 0);
        dp[0] = a[0];
        for (int i = 1; i < a.size(); i++)
            dp[i] = max(dp[i - 1] + a[i], a[i]);
        return *max_element(dp.begin(), dp.end());
    }
};

注意要考虑到全是负数的情况,分情况讨论即可,不过本题没有这个问题

代码如下:

#include <iostream>
#include <vector>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <queue>
#include <stack>
#include <string>
#include <climits>
#include <algorithm>
#include <sstream>
#include <functional>
#include <bitset>
#include <numeric>
#include <cmath>
#include <regex>
#include <iomanip>
#include <cstdlib>
#include <ctime>
#include <array>
using namespace std;



class Solution 
{
public:
    int maxSubArray(vector<int>& a) 
    {
        bool flag = false;
        for (int i=0;i<a.size();i++)
        {
            if (a[i] >= 0)
                flag = true;
        }

        if (flag == true)
        {
            int sum = 0;
            int dp = 0;
            for (int i = 0; i<a.size(); i++)
            {
                if (dp > 0)
                    dp += a[i];
                else
                    dp = a[i];

                sum = max(sum, dp);
            }
            return sum;
        }
        else
            return *max_element(a.begin(), a.end());
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值