434
社区成员
发帖
与我相关
我的任务
分享
#include <iostream>
#include <algorithm>
using namespace std;
int maxCrossingSubArray(int arr[], int left, int mid, int right);
int maxSubArray(int arr[], int left, int right) {
if (left == right) {
return arr[left];
}
int mid = left + (right - left) / 2;
int leftMax = maxSubArray(arr, left, mid);
int rightMax = maxSubArray(arr, mid + 1, right);
int crossMax = maxCrossingSubArray(arr, left, mid, right);
return max(max(leftMax, rightMax), crossMax);
}
int maxCrossingSubArray(int arr[], int left, int mid, int right) {
int leftSum = INT_MIN;
int sum = 0;
for (int i = mid; i >= left; i--) {
sum += arr[i];
leftSum = max(leftSum, sum);
}
int rightSum = INT_MIN;
sum = 0;
for (int i = mid + 1; i <= right; i++) {
sum += arr[i];
rightSum = max(rightSum, sum);
}
// 计算交叉和的最大值
int crossSum = leftSum + rightSum;
return crossSum;
}
int main() {
int n;
cin >> n;
int* nums = new int[n];
for (int i = 0; i < n; i++) {
cin >> nums[i];
}
int result = maxSubArray(nums, 0, n - 1); // 调用maxSubArray函数求解最大子段和
cout << result << endl;
delete[] nums; // 释放内存空间,防止内存泄漏问题出现。
}
该算法不断二分子问题,直到子问题可直接求解,主定理求解,
在每一次递归中,问题的规模缩小为原来的一半,需要线性时间O(n)来计算子问题的最大子数组和和交叉子数组和,划分子问题O(1)
因此,我们可以得出递归式:T(n) = 2T(n/2) + O(n) + O(1) = O(nlogn)
分治法的思想就是不断划分子问题,把问题变简单,直到足够简单能直接求解为止,在一层一层倒推回去原问题的解,在日常生活中,也可以用这种思想,把目前棘手的事分成几个小任务,一个个完成.