Maximum Subarray 解题

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.

click to show more practice.

More practice:

If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.

上述题目。

首先是O(n)解,利用动态规划。在每个位置要记录下当前位置的两个最大值:1)加到当前值得最大值和 2)当前的全局最大值

1)加到当前的最大值 要么是上一个位置的 1) 加上当前位置值,要么是当前位置值

2)全局最大值,要么是 本位置的 1), 要么是之前的 2)

因此,只需要两个变量来进行记录即可。

代码:

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int sum2cur = nums[0];
        int max2cur = nums[0];
        int n = nums.size();
        for(int i = 1; i < n;i++){
            sum2cur = max(sum2cur + nums[i], nums[i]);
            max2cur = max(max2cur, sum2cur);
        }
        return(sum2cur, max2cur);
    }
};
第二是题目要求的 divide and conquer 解,如何分治,一般2分用的比较顺手,可以尝试。

1. 选取数组的中间位置 middle, 最大值要么在左边,要么在右边,要么是左边 + middle + 右边。

2. 1)如果最大值在左边,那么就对左边进行递归;要是在右边就对右边递归;

2)如果最大值包含 middle,那么 最大值得序列一定是 左边的 后缀 + middle + 右边的 前缀,找到这个最大的后缀和前缀即可

3.求出上述三种情况的之后,返回最大值即可。

代码:

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        return helper(nums, 0, nums.size() - 1);
    }
    int helper(vector<int>& nums, int left, int right){
        if(left >= right)   return nums[left];
        int middle = (left + right) / 2;
        int leftmax = helper(nums, left, middle - 1);
        int rightmax = helper(nums, middle + 1, right);
        int suffix = 0;
        int prefix = 0;
        int tmp = 0;
        for(int i = middle - 1; i >= left;i--){
            tmp += nums[i];
            if(tmp > suffix)    suffix = tmp;
        }
        tmp = 0;
        for(int i = middle + 1; i <= right; i++){
            tmp += nums[i];
            if(tmp > prefix)    prefix = tmp;
        }
        return max(max(leftmax, rightmax), suffix + nums[middle] + prefix);
    }
};

that's all


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值