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、暴力枚举

起点:i=0,...,n-1;终点:j=i,....,n-1;依次求[i,j]区间的和,时间复杂度O(n^3)

2、优化枚举

起点:i=0,...,n-1;终点:j=i,....,n-1;累计求[i,j]区间的和,时间复杂度O(n^2)

3、分治算法

分:两个等长的子数组,分别求解,复杂度O(nlogn)

合:求包含中间点的最大子数组之和,复杂度O(n)

时间复杂度:O(nlogn)

4、动态规划

假设dp[i]表示以a[i]结尾的最大子数组和,那么

状态转移方程:

dp[i]=max(dp[i-1]+a[i],a[i])

  • 包含a[0,i-1]:dp[i-1]+a[i]
  • 不包含a[0,i-1]:a[i]

初始值:

dp[0]=a[0]

复杂度:

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

空间优化:

dp[i]只与dp[i-1]有关,因此状态转移方程优化为:

best=max(best+a[i],a[i])

其实这里的动态规划实现的是一种简单的逻辑,即前面的数组和大于0,则加上,小于或等于0,则放弃。

if(cur>0)
  cur+=A[i];
else
  cur=A[i];

5、前缀数组和

定义:sum[i]=a[0]+a[1]+...+a[i]

sum(A[i....j])=sum[j]-sum[i-1]

对于数组A,以A[i]结尾的最大子数组和为sum[i]-min(sum(k)),k=0...i-1,因此需保存每一步计算中的最小sum值。

依次计算以A[i]结尾的最大子数组和,然后保留其最大值即可,详见代码。

代码:

只实现分治、动态规划以及前缀和三种思路

1、分治

class Solution {
public:
int maxSubArray(int A[], int n) {
if(n==1)
return A[0]; int mid=n/2;
int left=maxSubArray(A,mid);
int right=maxSubArray(A+mid,n-mid);
int ans=max(left,right); int cur=A[mid-1];
int tmp=cur;
for(int i=mid-2;i>=0;i--){
cur+=A[i];
if(cur>tmp)
tmp=cur;
}
cur=tmp;
for(int i=mid;i<n;i++){
cur+=A[i];
if(cur>tmp)
tmp=cur;
} return max(ans,tmp); }
};

2、动态规划

class Solution {
public:
int maxSubArray(int A[], int n) {
int cur=A[0];
int max=A[0];
for(int i=1;i<n;i++){
if(cur>0)
cur+=A[i];
else
cur=A[i];
if(cur>max)
max=cur;
}
return max;
}
};
class Solution {
public:
int maxSubArray(int A[], int n) {
int endhere=A[0];
int ans=A[0]; for(int i=1;i<n;i++){
endhere=max(endhere+A[i],A[i]);
ans=max(ans,endhere);
} return ans;
}
};

3、前缀数组和

class Solution {
public:
int maxSubArray(int A[], int n) {
int sum=A[0];
int minSum=min(0,sum);
int ans=A[0]; for(int i=1;i<n;i++){
sum+=A[i];
ans=max(ans,sum-minSum);
minSum=min(minSum,sum);
} return ans;
}
};

  

(LeetCode 53)Maximum Subarray的更多相关文章

  1. leetcode || 53、Maximum Subarray

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

  2. LeetCode(53) Maximum Subarray

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

  3. (Problem 53)Combinatoric selections

    There are exactly ten ways of selecting three from five, 12345: 123, 124, 125, 134, 135, 145, 234, 2 ...

  4. 【算法】LeetCode算法题-Maximum Subarray

    这是悦乐书的第154次更新,第156篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第13题(顺位题号是53).给定一个整数数组nums,找出一个最大和,此和是由数组中索引 ...

  5. (LeetCode 78)SubSets

    Given a set of distinct integers, S, return all possible subsets. Note: Elements in a subset must be ...

  6. (LeetCode 72)Edit Distance

    Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2 ...

  7. 《从零开始学Swift》学习笔记(Day 53)——do-try-catch错误处理模式

    原创文章,欢迎转载.转载请注明:关东升的博客 Swift 1.x的错误处理模式存在很多弊端,例如:为了在编程时候省事,给error参数传递一个nil,或者方法调用完成后不去判断error是否为nil, ...

  8. 【LeetCode】053. Maximum Subarray

    题目: Find the contiguous subarray within an array (containing at least one number) which has the larg ...

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

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

随机推荐

  1. XV6操作系统代码阅读心得(三):锁

    锁是操作系统中实现进程同步的重要机制. 基本概念 临界区(Critical Section)是指对共享数据进行访问与操作的代码区域.所谓共享数据,就是可能有多个代码执行流并发地执行,并在执行中可能会同 ...

  2. Java synchronized的原理解析

    开始 类有一个特性叫封装,如果一个类,所有的field都是private的,而且没有任何的method,那么这个类就像是四面围墙+天罗地网,没有门.看起来就是一个封闭的箱子,外面的进不来,里面的出不去 ...

  3. /etc/default/useradd配置文件详解

    /etc/default/useradd文件内容如下: [xf@xuexi ~]$ cat /etc/default/useradd # useradd defaults file GROUP=100 ...

  4. Redis学习篇(一)之String类型及其操作

    SET 作用: 设置key对应的值, 返回ok 语法: SET key value [EX seconds] [PX milliseconds] [NX] [XX] 如果key已经存在,同名会产生覆盖 ...

  5. ARC 101 C - Candles

    题面在这里! 显然直接枚举左端点(右端点)就OK啦. #include<cstdio> #include<cstdlib> #include<algorithm> ...

  6. HDU 6119 小小粉丝度度熊(Two pointers)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=6119 [题目大意] 给出一些签到区间和一些补签卡,问可以创造的最长连续签到区间 [题解] 如果我们 ...

  7. 【动态规划/多重背包问题】POJ1014-Dividing

    多重背包问题的优化版来做,详见之前的动态规划读书笔记. dp[i][j]表示前i中数加得到j时第i种数最多剩余几个(不能加和得到i的情况下为-1)递推式为: dp[i][j]=mi(dp[i-1][j ...

  8. DML、DDL、DCL是什么?

    一.DML DML(data manipulation language)数据操纵语言: 我们经常会用到的 INSERT.DELETE.UPDATE.SELECT语句. 主要用来对数据库的数据进行一些 ...

  9. BZOJ 2653 middle 二分答案+可持久化线段树

    题目大意:有一个序列,包含多次询问.询问区间左右端点在规定区间里移动所得到的最大中位数的值. 考虑对于每个询问,如何得到最优区间?枚举显然是超时的,只能考虑二分. 中位数的定义是在一个序列中,比中位数 ...

  10. PHP -- 模拟测试上传文件

    FROM :http://web.itivy.com/article-740-1.html QQ上传文件为什么那么快? “QQ上传大文件/QQ群发送大文件时,可以在极短的时间内完成”是如何做到的. 有 ...