问题描述:存在序列A[1...n],序列中元素的值域为整数。求解序列A中子序列A[p,...,q]的元素和为最大值子序列?
解决思路 : 设m为↓[(1+n)/2]向下取整的即中点,则A最大值子序列在是下面序列中最大值子序列中之一
A[1,...,m](中点左侧 包括中点)
A[i,...,j] 其中1 <= i <= m < j <= n (横跨中点)
A[m+1,n](中点右侧 不包括中点)
这样将求A最大值子序列问题转移求A[1,...,m]、A[i,...,j] 其中1 <= i <= m < j <= n 、A[m+1,n]三者中最大值子序列的问题,获取三者种最大一个;
1 先来获取A[i,...,j] 其中1 <= i <= m < j <= n中最大子序列(横跨中点)
伪代码如下:
序列
FIX-MAX-CROSSING-SUBARRAY(A , low , mid , high) {
// 先求A[low , mid]这端子序列最大值,因为要包括mid所以从mid开始
left-sum = -∞;
sum = 0;
max-left;
for (i = mid; i >= low; i++) {
sum = sum + A[i];
if(sum > letf-sum) {
left-sum = sum;
max-left = i;
}
}
// 再求A[mid+1, high]这端子序列最大值
right-sum = -∞;
sum = 0;
max-right;
for(i = mid+1; i <= high; i++) {
sum = sum + A[i];
if(sum > right-sum) {
right-sum = sum;
max-right = i;
}
}
return (max-left , max-right , left-sum+right-sum);
}
这样就可以获取A[i,...,j] 其中1 <= i <= m < j <= n中最大子序列(横跨中点)
2 A[1,...,m](中点左侧 包括中点) 和 A[i,...,j] 其中1 <= i <= m < j <= n (横跨中点) ,俩个序列 像针对A序列一样进行分解,
直到分解成序列中元素只有1位,并且每次分解都需要调用 FIX-MAX-CROSSING-SUBARRAY(A , low , mid , high) 获取横跨中点序列的最大值;
伪代码如下 :
FIND-MAXIMUM-SUBARRAY(A , low , high) {
if (low == high) {
// 分解序列元素为1停止
return (low , high , A[low])
} else {
// 每次分解序列工作
mid = ↓[(low+high)/2];
// 分解中点左右俩端序列
(left-low , left-high , left-sum) = FIND-MAXIMUM-SUBARRAY(A , low , mid);
(right-low , right-high , right-sum) = FIND-MAXIMUM-SUBARRAY(A , mid+1 , high);
// 求出包含中点元素的序列的最大子序列
(cross-low , cross-high , cross-sum) = FIX-MAX-CROSSING-SUBARRAY(A , low , mid , high)
// 获取三个子序列中最大值最大那个
if(left-sum >= right-sum and left-sum >= cross-sum) {
return (left-low , left-high , left-sum)
} else if(right-sum >= left-sum and right-sum >= cross-sum) {
return (right-low , right-high , right-sum)
} else {
return (cross-low , cross-high , cross-sum)
}
}
}
通过递归调用可以求出序列A子序列和最大值问题
时间复杂度影响因素 : 序列项数
时间复杂度 : Θ(nlgn)