小目标 To be or not to be

Leetcode 053 Maximun subarray

2017-02-27
chaowyc

Leetcode 053 题

Difficulty:Easy

Tag: Dynamic Programming, Divide and Conquer

题目

题目原址:https://leetcode.com/problems/maximum-subarray/?tab=Description

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.

思路1-动态规划

利用动态规划的思想,设 $dp[i]$ 为 数组 $nums[0..i]$ 的元素和的最大值。

所以,$dp[i] = \max(dp[i - 1] + nums[i], dp[i - 1])$

代码1-动态规划

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

思路2-分治

将数组分而治之,会有三种情况

假设数组 nums[left, right] 存在最大区间,mid = (left + right) /2
情况1: 最大值在 nums[left, mid - 1]里
情况2: 最大值在 nums[mid + 1, right]里
情况3: 最大值横跨三个部分,即nums[left, mid -1]的最大值加上nums[mid + 1, right]的最大值,再加上mid为最终的值。

代码2-分治

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int MAX = INT_MIN;
        return divide(nums, 0, nums.size() - 1, MAX);
    }
    int divide(vector<int>& nums, int left, int right, int dmax)
    {
        //base 
        if(left > right) return dmax;
        
        //处理情况1和2
        int mid = left + (right - left) / 2;
        
        //获得区间 nums[left, mid -1]的最大值
        int lmax = divide(nums, left, mid - 1, dmax);
        
        //获得区间 nums[mid + 1, right]的最大值
        int rmax = divide(nums, mid + 1, right, dmax);
        dmax = max(lmax, dmax);
        dmax = max(rmax, dmax);
        
        //处理情况3
        
        int sum = 0;
        int mlmax = 0;
        for(int i = mid - 1; i >= left; i--)
        {
            sum += nums[i];
            mlmax = max(sum, mlmax);
        }
        
        sum = 0;
        int mrmax = 0;
        for(int i = mid + 1; i <= right; i++)
        {
            sum += nums[i];
            mrmax = max(sum, mrmax);
        }
        //返回三种情况中最大的
        dmax = max(dmax, mlmax + nums[mid] + mrmax);
        return dmax;
    }
};

Similar Posts

Comments