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)
理解题目之后还是觉得此题没太大必要用分治法.