经典最大子串和问题,要求用两种方法实现:1、Kadane算法,复杂度O(n); 2、分治法,复杂度O(nlogn)。
1、Kadane算法:代码比较简单,但是理解需要时间。初始化ans为0, 每次用ans加上A[i]的值,并更新最大值,如果遇到ans<0,更新ans的值为0。
class Solution {
public:
int maxSubArray(int A[], int n) {
// Note: The Solution object is instantiated only once and is reused by each test case.
int ans = 0, maxn = INT_MIN;
for(int i = 0; i < n; i++){
if(ans < 0) ans = 0;
ans += A[i];
maxn = max(maxn, ans);
}
return maxn;
}
};
2、分治法:最大子串和的区间有以下三种情况(low,high分别为左右边界,mid为(low+high)/2):
(1) 区间完全在 A[low,mid-1]
(2) 区间完全在 A[mid+1,high]
(3) 区间包含有 A[mid]
按照这三种情况一直递归下去即可。
class Solution {
public:
int divide(int A[], int low, int high){
if(low == high) return A[low];
if(low == high-1)
return max(A[low]+A[high], max(A[low], A[high]));
int mid = (low+high)/2;
int lmax = divide(A, low, mid-1);
int rmax = divide(A, mid+1, high);
int mmax = A[mid];
int tmp = mmax;
for(int i = mid-1; i >=low; i--){
tmp += A[i];
if(tmp > mmax) mmax = tmp;
}
tmp = mmax;
for(int i = mid+1; i <= high; i++){
tmp += A[i];
if(tmp > mmax) mmax = tmp;
}
return max(mmax, max(lmax, rmax));
}
int maxSubArray(int A[], int n) {
// Note: The Solution object is instantiated only once and is reused by each test case.
return divide(A, 0, n-1);
}
};