(LeetCode 53)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
.
题目:
最大子数组和
思路:
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的更多相关文章
- leetcode || 53、Maximum Subarray
problem: Find the contiguous subarray within an array (containing at least one number) which has the ...
- LeetCode(53) Maximum Subarray
题目 Find the contiguous subarray within an array (containing at least one number) which has the large ...
- (Problem 53)Combinatoric selections
There are exactly ten ways of selecting three from five, 12345: 123, 124, 125, 134, 135, 145, 234, 2 ...
- 【算法】LeetCode算法题-Maximum Subarray
这是悦乐书的第154次更新,第156篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第13题(顺位题号是53).给定一个整数数组nums,找出一个最大和,此和是由数组中索引 ...
- (LeetCode 78)SubSets
Given a set of distinct integers, S, return all possible subsets. Note: Elements in a subset must be ...
- (LeetCode 72)Edit Distance
Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2 ...
- 《从零开始学Swift》学习笔记(Day 53)——do-try-catch错误处理模式
原创文章,欢迎转载.转载请注明:关东升的博客 Swift 1.x的错误处理模式存在很多弊端,例如:为了在编程时候省事,给error参数传递一个nil,或者方法调用完成后不去判断error是否为nil, ...
- 【LeetCode】053. Maximum Subarray
题目: Find the contiguous subarray within an array (containing at least one number) which has the larg ...
- LeetCode OJ:Maximum Subarray(子数组最大值)
Find the contiguous subarray within an array (containing at least one number) which has the largest ...
随机推荐
- XV6操作系统代码阅读心得(三):锁
锁是操作系统中实现进程同步的重要机制. 基本概念 临界区(Critical Section)是指对共享数据进行访问与操作的代码区域.所谓共享数据,就是可能有多个代码执行流并发地执行,并在执行中可能会同 ...
- Java synchronized的原理解析
开始 类有一个特性叫封装,如果一个类,所有的field都是private的,而且没有任何的method,那么这个类就像是四面围墙+天罗地网,没有门.看起来就是一个封闭的箱子,外面的进不来,里面的出不去 ...
- /etc/default/useradd配置文件详解
/etc/default/useradd文件内容如下: [xf@xuexi ~]$ cat /etc/default/useradd # useradd defaults file GROUP=100 ...
- Redis学习篇(一)之String类型及其操作
SET 作用: 设置key对应的值, 返回ok 语法: SET key value [EX seconds] [PX milliseconds] [NX] [XX] 如果key已经存在,同名会产生覆盖 ...
- ARC 101 C - Candles
题面在这里! 显然直接枚举左端点(右端点)就OK啦. #include<cstdio> #include<cstdlib> #include<algorithm> ...
- HDU 6119 小小粉丝度度熊(Two pointers)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=6119 [题目大意] 给出一些签到区间和一些补签卡,问可以创造的最长连续签到区间 [题解] 如果我们 ...
- 【动态规划/多重背包问题】POJ1014-Dividing
多重背包问题的优化版来做,详见之前的动态规划读书笔记. dp[i][j]表示前i中数加得到j时第i种数最多剩余几个(不能加和得到i的情况下为-1)递推式为: dp[i][j]=mi(dp[i-1][j ...
- DML、DDL、DCL是什么?
一.DML DML(data manipulation language)数据操纵语言: 我们经常会用到的 INSERT.DELETE.UPDATE.SELECT语句. 主要用来对数据库的数据进行一些 ...
- BZOJ 2653 middle 二分答案+可持久化线段树
题目大意:有一个序列,包含多次询问.询问区间左右端点在规定区间里移动所得到的最大中位数的值. 考虑对于每个询问,如何得到最优区间?枚举显然是超时的,只能考虑二分. 中位数的定义是在一个序列中,比中位数 ...
- PHP -- 模拟测试上传文件
FROM :http://web.itivy.com/article-740-1.html QQ上传文件为什么那么快? “QQ上传大文件/QQ群发送大文件时,可以在极短的时间内完成”是如何做到的. 有 ...