分治法求最大连续和

给出一个长度为n的序列,求连续最大和。


递归求解是分别求出位于左半部分和右半部份的最优解。


合并是找起点在左边的,终点在右边的最优解,并和左右部分最优的进行比较。


代码如下。


时间复杂度o(NlogN)

int maxsum(int *A, int x, int y){
    int middle, value, L, R, mmax;

    if(y-x == 1)
        return A[x];   ///只有一个元素,直接返回

    middle = x + (y-x)/2;    ///第一步:划分区间为[x,m) [m,y)
    mmax = max(maxsum(A, x, middle), maxsum(A, middle, y));    ///第二步:递归求解

    value = 0;      ///第三步:从分界点开始向左的最大连续和L
    L = A[middle-1];
    for(int i = middle-1; i >= x; i--){
        value += A[i];
        L = max(L, value);
    }

    value = 0;        ///第三步:从分界点开始向右的最大连续和R
    R = A[middle];
    for(int i = middle; i < y; i++){
        value += A[i];
        R = max(R, value);
    }

    return max(mmax, (L+R));   ///二者比较取最大
}

以下是使用分治法最大连续字段和的 C++ 代码实现: ```c++ #include <iostream> #include <vector> using namespace std; // 分治法最大连续字段和 int maxSubArray(vector<int>& nums, int left, int right) { if (left == right) { return nums[left]; } int mid = (left + right) / 2; int leftSum = maxSubArray(nums, left, mid); int rightSum = maxSubArray(nums, mid + 1, right); int crossSum = nums[mid]; int crossLeftSum = nums[mid]; for (int i = mid - 1; i >= left; i--) { crossLeftSum += nums[i]; crossSum = max(crossSum, crossLeftSum); } int crossRightSum = nums[mid + 1]; int crossSumRight = nums[mid + 1]; for (int i = mid + 2; i <= right; i++) { crossRightSum += nums[i]; crossSumRight = max(crossSumRight, crossRightSum); } crossSum += crossSumRight; return max(crossSum, max(leftSum, rightSum)); } int main() { vector<int> nums = {-2, 1, -3, 4, -1, 2, 1, -5, 4}; int n = nums.size(); int res = maxSubArray(nums, 0, n - 1); cout << "The maximum sum of the contiguous subarray is: " << res << endl; return 0; } ``` 在这个代码中,我们定义了一个 `maxSubArray` 函数,用于计算指定数组中的最大连续子数组和。该函数使用分治法的思想,将给定数组分成左右两个子数组,并递归出左右子数组的最大连续子数组和。然后计算跨越左右子数组的最大连续子数组和,并返回三个值中的最大值。在计算跨越左右子数组的最大连续子数组和时,我们使用了两个循环分别计算左右两个子数组中的最大连续子数组和。最后,在主函数中调用 `maxSubArray` 函数,并打印结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值