53.Maximum Subarray



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.

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.

题意

找出一个和最大的子数组.注意这里的子数组是连续的.
可以用两种方法:
1. Kadane算法: O(n)
2. 分治法: O(nlogn)

Kadane算法

描述

Kadane算法属于动态规划
定义两个变量 result curSum ,其中 result 保存最终要返回的结果,即最大的子数组之和, curSum 初始值为0,是一个临时变量
每遍历一个数字 num :
1. 比较 curSum+num num 中的较大值存入 curSum
2. 然后再把 result curSum 中的较大值存入 result

具体实现

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

};

复杂度分析

时间复杂度: O(n)
空间复杂度: O(1)

分治法

描述

分治法:最大子串和的区间有以下三种情况(low,high分别为左右边界,mid为(low+high)/2):
(1) 区间完全在 A[low,mid-1]
(2) 区间完全在 A[mid+1,high]
(3) 区间包含有 A[mid], 从中间开始,往左右两侧扫描

具体实现

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        return divide(nums, 0, nums.size()-1);
    }
    int divide(vector<int>& nums, int low, int high){  
        if(low == high) return nums[low];  
        if(low == high-1)
            return max(nums[low]+nums[high], max(nums[low], nums[high]));  

        int mid = (low+high)/2;  

        int lmax = divide(nums, low, mid-1);  // left max
        int rmax = divide(nums, mid+1, high);  // right max

        int mmax = nums[mid];  // middle max
        int tmp = mmax;  
        for(int i = mid-1; i >=low; i--){  
            tmp += nums[i];  
            if(tmp > mmax)  mmax = tmp;  
        }  
        tmp = mmax;  
        for(int i = mid+1; i <= high; i++){  
            tmp += nums[i];  
            if(tmp > mmax)  mmax = tmp;  
        }  

        return max(mmax, max(lmax, rmax));  
    } 
};

复杂度分析

时间复杂度: O(nlogn)
理解题目之后还是觉得此题没太大必要用分治法.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值