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.

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.


【题目分析】

题目要求我们在给定的一个数组中找出一个数组元素之和最大子数组,并返回最大的和。


【思路】 动态规划

max_sum 必然是以A[i](取值范围为A[0] ~ A[n-1])结尾的某段构成的,也就是说max_sum的candidate必然是以A[i]结果的。如果遍历每个candidate,然后进行比较,那么就能找到最大的max_sum了。

假设把A[i]之前的连续段叫做sum。可以很容易想到:

1. 如果sum>=0,就可以和A[i]拼接在一起构成新的sum'。因为不管A[i]多大,加上一个正数总会更大,这样形成一个新的candidate。

2. 反之,如果sum<0,就没必要和A[I]拼接在一起了。因为不管A[i]多小,加上一个负数总会更小。此时由于题目要求数组连续,所以没法保留原sum,所以只能让sum等于从A[i]开始的新的一段数了,这一段数字形成新的candidate。

3. 如果每次得到新的candidate都和全局的max_sum进行比较,那么必然能找到最大的max sum subarray.

在循环过程中,用max_sum记录历史最大的值。从A[0]到A[n-1]一步一步地进行。

其实上面的思想是最简单的动态规划的思想,用maxl[i]数组表示包含i元素的子数组的最大和,则动态规划的递推公式为:maxl[i+1] = max(maxl[i]+A[i], A[i+1]),即最大值一定是数组当前元素以及数组当前元素和前一结果之和的最大值。接下来整个问题的最大值就是maxl数组中的最大值。

面的分析过程是一个简单的动态规划,这个算法叫做 Kadane's algorithm,参加维基百科:https://en.wikipedia.org/wiki/Maximum_subarray_problem

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


【思路2】 分而治之

问题解决了,可是发现了下面的拓展,即分治解决。提到分治,思路来了,当前的最大值等于左侧最大值和右侧最大值中较大的。可是,有一点点问题,这个最大值还有可能是横跨左右两侧的啊。。。

于是,在处理两侧的子问题的时候,需要同时分别计算包含最左端元素的最大值(lres)和包含最右端元素的最大值(rres)。这样,当前的最大值就为“左侧最大值(res1)”、“右侧最大值(res2)”、“左侧含最右端元素的最大值(rres1)及右侧包含最左端元素的最大值(lres2)之和”三者的最大值。

而由于lres可分为只在左侧和也包含右侧两种情况:

  • 左侧含最左端元素的最大值(lres1)
  • 左侧元素之和加右侧含最左端元素的最大值(all1+lres2)

含最右端元素的最大值同理,即lres = max(lres1, all1 + lres2)和rres = max(rres2, all2 + rres1)。

问题得以解决。至于时间复杂度,个人认为,是n/2 + n/4 + n/8 + ... = O(n)。


【java代码】 动态规划

 public class Solution {
public int maxSubArray(int[] nums) {
if(nums == null || nums.length == 0) return 0; int length = nums.length;
if (length == 1){
return nums[0];
}
int currentsum = nums[0];
int maxsum = nums[0];
for (int i = 1; i < length; i++){
if (currentsum >= 0){
currentsum += nums[i];
} else{
currentsum = nums[i];
} maxsum = maxsum > currentsum ? maxsum : currentsum;
} return maxsum;
}
}
【C++代码】分而治之
 class Solution{
public:
int maxSubArray(int A[], int n){
int res, lres, rres, all;
maxSubArray(A, , n - , res, lres, rres, all);
return res;
}
private:
void maxSubArray(int A[], int l, int r, int &res, int &lres, int &rres, int &all){
if(l == r)
{
res = lres = rres = all = A[l];
return;
} int m = (l + r) / ;
int res1, lres1, rres1, all1, res2, lres2, rres2, all2; maxSubArray(A, l, m, res1, lres1, rres1, all1);
maxSubArray(A, m + , r, res2, lres2, rres2, all2); res = max(max(res1, res2), rres1 + lres2);
lres = max(lres1, all1 + lres2);
rres = max(rres2, all2 + rres1);
all = all1 + all2;
}
};
 

LeetCode OJ 53. Maximum Subarray的更多相关文章

  1. [Leetcode][Python]53: Maximum Subarray

    # -*- coding: utf8 -*-'''__author__ = 'dabay.wang@gmail.com' 53: Maximum Subarrayhttps://leetcode.co ...

  2. Leetcode之53. Maximum Subarray Easy

    Leetcode 53 Maximum Subarray Easyhttps://leetcode.com/problems/maximum-subarray/Given an integer arr ...

  3. 【LeetCode】53. Maximum Subarray (2 solutions)

    Maximum Subarray Find the contiguous subarray within an array (containing at least one number) which ...

  4. 【一天一道LeetCode】#53. Maximum Subarray

    一天一道LeetCode系列 (一)题目 Find the contiguous subarray within an array (containing at least one number) w ...

  5. 【LeetCode】53. Maximum Subarray 最大子序和 解题报告(Python & C++ & Java)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 暴力解法 动态规划 日期 题目地址: https:/ ...

  6. [leetcode DP]53. Maximum Subarray

    Find the contiguous subarray within an array (containing at least one number) which has the largest ...

  7. LeetCode OJ:Maximum Subarray(子数组最大值)

    Find the contiguous subarray within an array (containing at least one number) which has the largest ...

  8. 【Leetcode】53. Maximum Subarray

    题目地址: https://leetcode.com/problems/maximum-subarray/description/ 题目描述: 经典的求最大连续子数组之和. 解法: 遍历这个vecto ...

  9. Leetcode No.53 Maximum Subarray(c++实现)

    1. 题目 1.1 英文题目 Given an integer array nums, find the contiguous subarray (containing at least one nu ...

随机推荐

  1. [MFC美化] SkinMagic使用详解2- SkinMagic常用函数介绍

    SkinMagic常用函数介绍 (1)InitSkinMagicLib函数:初始化SkinMagic int InitSkinMagicLib( //初始化SkinMagic工具库 HINSTANCE ...

  2. gulp 安装步骤

    第一步:安装node 搭建node环境:进入官网 http://nodejs.org  ,然后点击的绿色的 install 按钮,下载完成后直接运行程序. 第二步:使用命令行 (1)输入指令:node ...

  3. ubuntu14通过trove/redstack安装openstack环境

    ---恢复内容开始--- Trove Installation Trove is constantly under development. The easiest way to install Tr ...

  4. AnimatorController反向运动学IK

    通过使用反向运动学IK,我们可以根据需要控制角色身体某个特定部位进行旋转或移动,达到想要的一些效果,比如:在移动时,让一只脚带伤拖行:让手抬起去拿桌上的苹果:让脑袋一直面向我们的色像机,就像一直注视着 ...

  5. Visual Studio 2010 使用外部代码格式化工具 AStyle

    其中AStyle.exe 最好自己编译,放置到 Vistual Studio 安装目录\\Common7\\Tools 直接上配置截图: 单文件: 一次性格式化整个工程:

  6. WPF Image Binding Uri Source 失败解决办法

    在ListView 的ListItem里动态绑定Image. 首先代码写的是没有问题的.但最后运行却无法显示图片.先看代码: 1. XAML部分 代码如下: <ListView x:Name=& ...

  7. Flex 国际化(中英语言适配)

    原文地址:http://www.cnblogs.com/meteoric_cry/archive/2011/01/13/1934404.html(由于此贴时间久远,已做微调) 1.新建Flex Pro ...

  8. 在.Net MVC中自定义ValidationAttribute标签对Model中的属性做验证

    写一个继承与ValidationAttribute类的自定义的验证方法 MVC中传递数据时,大多数都会用Model承载数据,并且在传到控制器后,对Model进行一系列的验证. 我平时经常使用的判断方法 ...

  9. md5证书在window2012不能访问

    之前在window 2008使用makecert的产生的证书,部署到window 2012后,发现只有IE能访问,但是Firefox和chrome都不行.Firefox可以使用about:config ...

  10. python操作---RabbitMQ

    RabbitMQ是一个在AMQP基础上完整的,可复用的企业消息系统.他遵循Mozilla Public License开源协议. MQ全称为Message Queue, 消息队列(MQ)是一种应用程序 ...