算法设计与分析第二章作业_计科2201徐彬

0zxm 2022级 2023-10-27 21:14:38
#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)

 

思考与体会

分治法的思想就是不断划分子问题,把问题变简单,直到足够简单能直接求解为止,在一层一层倒推回去原问题的解,在日常生活中,也可以用这种思想,把目前棘手的事分成几个小任务,一个个完成.

...全文
31 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

434

社区成员

发帖
与我相关
我的任务
社区描述
广东外语外贸大学信息科学与技术学院
算法 高校
社区管理员
  • brisksea
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧