【题目】
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.
【分析】
详细参考:编程之美之2.14 求数组的子数组之和的最大值
【代码】
/*********************************
* 日期:2015-01-27
* 作者:SJF0115
* 题目: 53.Maximum Subarray
* 网址:https://oj.leetcode.com/problems/maximum-subarray/
* 结果:AC
* 来源:LeetCode
* 博客:
**********************************/
#include <iostream>
#include <climits>
using namespace std;
class Solution {
public:
int maxSubArray(int A[], int n) {
if(n <= 0){
return 0;
}//if
// 最大和
int max = A[0];
// 当前最大和
int cur = 0;
for(int i = 0;i < n;++i){
// 一旦当前最大和小于0就重置为0,一个负数只能使最大和变小
if(cur < 0){
cur = 0;
}//if
cur += A[i];
if(cur > max){
max = cur;
}//if
}//for
return max;
}
};
int main(){
Solution solution;
int n = 9;
int A[] = {-2,1,-3,4,-1,2,1,-5,4};
int result = solution.maxSubArray(A,n);
// 输出
cout<<result<<endl;
return 0;
}
【分析二】
如果将所给数组(A[0],...,A[n-1])分为长度相等的两段数组(A[0],...,A[n/2-1])和(A[n/2],...,A[n-1]),分别求出这两段数组各自最大子段和,
则原数组(A[0],...,A[n-1])的最大子段和分为以下三种情况,要么在前半部分a中,要么在后半部分b中,要么跨越a和b之间的边界:
a.(A[0],...,A[n-1])的最大子段和与(A[0],...,A[n/2-1])的最大子段和相同;
b.(A[0],...,A[n-1])的最大子段和与(A[n/2],...,A[n-1])的最大子段和相同;
c.(A[0],...,A[n-1])的最大子段跨过其中间两个元素A[n/2-1]到A[n/2];
对应a和b两个问题是规模减半的两个相同的子问题,可以用递归求得。
对于c,需要找到以A[n/2-1]结尾的最大的一段连续数组之和S1=(A[i],...,A[n/2-1])和以A[n/2]开始的最大的一段连续数组之和S2=(A[n/2],...,A[j]),那么第三种情况的最大值为S1+S2。
只需要对原数组进行一次遍历即可。在a中的部分是a中包含右边界的最大子数组,在b中的部分是b中包含左边界的最大子数组。
这其实是一种分治策略,时间复杂度为O(nlogn)。
【代码二】
/*********************************
* 日期:2015-02-03
* 作者:SJF0115
* 题目: 53.Maximum Subarray
* 网址:https://oj.leetcode.com/problems/maximum-subarray/
* 结果:AC
* 来源:LeetCode
* 博客:
**********************************/
#include <iostream>
#include <climits>
using namespace std;
class Solution {
public:
int maxSubArray(int A[], int n) {
return Divide(A,0,n-1);
}
private:
int Divide(int A[],int left,int right){
if(left > right){
return 0;
}//if
if(left == right){
return A[left];
}//if
//
int mid = left + (right - left) / 2;
//1.跨越a和b之间的部分
//1.1在a中的部分是a中包含右边界的最大子数组
int sum = 0;
int leftMax = A[mid];
for(int i = mid;i >= left;--i){
sum += A[i];
leftMax = max(sum,leftMax);
}//for
//1.2在b中的部分是b中包含左边界的最大子数组
sum = 0;
int rightMax = A[mid+1];
for(int i = mid+1;i <= right;++i){
sum += A[i];
rightMax = max(sum,rightMax);
}//for
// 前半部分最大和
int aMax = Divide(A,left,mid);
// 后半部分最大和
int bMax = Divide(A,mid+1,right);
// 跨越mid的最大和
int cMax = leftMax + rightMax;
return max(max(aMax,bMax),cMax);
}
};
int main(){
Solution solution;
int n = 9;
int A[] = {-2,1,-3,4,-1,2,1,-5,4};
//int A[] = {-9,-2,-3,-5,-3};
//int A[] = {0,-2,3,5,-1,2};
int result = solution.maxSubArray(A,n);
// 输出
cout<<result<<endl;
return 0;
}
【分析三】
只遍历数组一遍,当从头到尾部遍历数组A, 遇到一个数有两种选择 (1)加入之前subArray (2)自己另起一个subArray
设状态S[i], 表示以A[i]结尾的最大连续子序列和,状态转移方程如下:
S[i] = max(S[i-1] + A[i],A[i])
时间复杂度:O(n) 空间复杂度:O(n)
【代码三】
/*--------------------------------------------
* 日期:2015-02-03
* 作者:SJF0115
* 题目: 53.Maximum Subarray
* 网址:https://oj.leetcode.com/problems/maximum-subarray/
* 结果:AC
* 来源:LeetCode
* 博客:
-----------------------------------------------*/
class Solution {
public:
int maxSubArray(int A[], int n) {
int S[n];
int maxSum = A[0];
S[0] = A[0];
// 动态规划
for(int i = 1;i < n;i++){
S[i] = max(S[i-1] + A[i],A[i]);
if(S[i] > maxSum){
maxSum = S[i];
}//if
}//for
return maxSum;
}
};
【解法四】
对前一个方法继续优化,从状态转移方程上S【i】只与S【i-1】有关,与其他都无关,因此可以用一个变量来记住前一个的最大连续数组和就可以了。
这样就可以节省空间了。
时间复杂度:O(n) 空间复杂度:O(1)
【代码四】
/*--------------------------------------------
* 日期:2015-02-03
* 作者:SJF0115
* 题目: 53.Maximum Subarray
* 网址:https://oj.leetcode.com/problems/maximum-subarray/
* 结果:AC
* 来源:LeetCode
* 博客:
-----------------------------------------------*/
class Solution {
public:
int maxSubArray(int A[], int n) {
int maxSum = A[0];
// sum 记住前一个的最大连续数组和
int sum = 0;
// 动态规划
for(int i = 0;i < n;i++){
sum += A[i];
sum = max(sum,A[i]);
if(sum > maxSum){
maxSum = sum;
}//if
}//for
return maxSum;
}
};
分享到:
相关推荐
Maximum XOR With an Element From ArraysubSequence问题一般可以用DP解决,复杂度为O(N ^ 2) subArray问题一般可以使用滑动窗口方法(或以DP结尾,在这种情况下本质也是一种滑动窗口方法),复杂度O(N) classic...
加油站 leetcode 【演示记录】 报告 展示 2017/03/06 1.二和,167....2107/03/06 ...53.Maximum Subarray, 91.Decode Ways, 96.Unique Binary Search Tree, 120.Triangle, 139.Word Break, 152.Maximum Produ
318| [Maximum Product of Word Lengths](https://leetcode.com/problems/maximum-product-of-word-lengths/) | [C++](./C++/maximum-product-of-word-lengths.cpp) [Python](./Python/maximum-product-of-word-...
53.Maximum Subarray 70.Climbing Stairs 121.Best Time to Buy and Sell Stock 122.Best Time to Buy and Sell Stock II 123.Best Time to Buy and Sell Stock III 141.Linked List Cycle 142.Linked List Cycle II...
Maximum Subarray [53]5. House Robber [198]6. Range Sum Query - Immutable [303]7. Counting Bits [338]8. Palindromic Substrings [647]9. Maximum Length of Pair Chain [646]10. Integer Break [343]11. ...
Subarray] [70. Climbing Stairs] [101. Symmetric Tree] [104. Maximum Depth of Binary Tree] [121. Best Time to Buy and Sell Stock] [167. Two Sum II - Input array is sorted] Medium [2. Add Two Numbers]
easy_Maximum-Subarray 提交链接 / Submit (You need register/login first before submit.) (在提交前你需要先注册或登录) 题目描述 / Description Given an integer array nums, find the contiguous subarray ...
收集面试中提出的一些重要问题。 数据结构算法面试问题面试中提出的一些重要...subarray/ https://leetcode.com/problems/first -missing-positive / https://leetcode.com/problems/container-with-most-water/ htt
动态规划——最大连续子序列和一维最大连续子序列和[x] LeetCode 53 Maximum Subarray设$d[i]$表示以序列中$s[i]$结尾的最大
java lru leetcode :ice_cream: LeetCode Kindem 的个人 LeetCode 题解仓库,欢迎交流学习。 下面的目录中 ...LeetCode ...LeetCode ...Subarray 55 Jump Game 56 Merge Intervals 64 Minimum Path Sum 73
Maximum 255. Verify Preorder Sequence in Binary Search Tree 907. Sum of Subarray Minimums 二叉搜索树 99. Recover Binary Search Tree 109. Convert Sorted List to Binary Search Tree 116. Populating Next ...
leetcode怎么销号 LeetCode-Solutions :green_heart:My own LeetCode solutions ...Subarray Easy 动态规划 0069 Sqrt(x) Easy 二分、牛顿迭代 0070 Climbing Stairs Easy 动态规划 0075 Sort Colors M
leetcode 分类leetcode 问题分类 leetcode代码仓库,我的解题思路写在我的博客里: ...#53:Maximum Subarray 队列/集 #3:Longest Substring Without Repeating Characters 优先队列 #23:Merge k Sorted Lists
leetcode 答案LeetCode LeetCode in Swift 这个Repo 用来存下我在LeetCode 解题的原始档,包含解题中遇到的错误,也...Subarray Easy #66 Plus One Easy #70 Climbing Stairs Easy #83 Remove Duplicates from Sorted L
活动选择(Activity Selection) 备选列表排列(Alternative List Arrange) Davis–Putnam–Logemann–Loveland算法 ...最大子数组(Maximum Subarray) 最大子序列(Maximum Subsequence) 嵌套括号(Nested Brackets
对于每一道算法题会总结代码、时间复杂度以及一些好的blog排序(sort)数组...53 Maximum SubarrayLeetCode 152 Maximum Product SubarrayLintCode 138 Subarray SumLintCode 139 Subarray Sum ClosestLeetCode 392 Is ...
Maximum Subarray Minimum Path Sum Unique Paths Unique Paths II Longest Palindromic Substring Interleaving String Triangle Distinct Subsequences Decode Ways Palindrome Partitioning II Maximal Rectangle...
leetcode 分类 LeetCode 152/152 ToDoList -1。 delete ...Subarray 是一个东西么? 18.汉诺塔 排序堆的建立..... 推排序 相当于优先队列 19.图的算法 kruskal prim dijstria flordy 似乎都拼错了。
最大子序和](./Array/maximum-subarray.md) [0041 缺失的第一个整数](./Array/first-missing-positive.md) [0042 接雨水](./Array/trapping-rain-water.md) [0048 旋转图像](./Array/rotate-image.md) Heap 堆 [0023...
leetcode中国大批 0. Count Prime 1. Reverse the array 2. Find the maximum and minimum element in an array 3. Find the "Kth" max and min element of an array 4. Given an array which consists of only 0, 1...