leetcode 53. Maximum Subarray DP+最大子串和

来源:互联网 发布:shell脚本与python 编辑:程序博客网 时间:2024/05/29 16:29

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 <string>#include <algorithm>#include <climits>using namespace std;class Solution {public:    int maxSubArray(vector<int>& nums)     {        int dp = 0;        int sum = numeric_limits<int>::min();        for (int i = 0; i < nums.size(); i++)        {            if (dp > 0)                dp += nums[i];            else                dp = nums[i];            sum = max(sum, dp);        }        return sum;    }};
阅读全文
0 0