c++算法学习,最大区间

给定一个实数序列,设计一个最有效的算法,找到一个总和数最大的区间 

#include <iostream>
#include <vector>
#include <limits>

// 结果结构体,用于存储最大子数组的信息
struct Result {
    int maxSum; // 最大和
    int start;  // 子数组的起始索引
    int end;    // 子数组的结束索引
};

// 查找最大子数组的函数,基于 Kadane 算法
Result findMaxSubarray(const std::vector<double>& arr) {
    double maxSoFar = std::numeric_limits<double>::lowest(); // 初始化最大和为负无穷
    double maxEndingHere = 0; // 当前子数组的和
    int start = 0, end = 0, s = 0; // 记录最大子数组的起始和结束索引
    
    Result result; // 创建结果对象
    result.maxSum = 0; // 初始化结果的最大和为0
    result.start = 0; // 初始化结果的起始索引为0
    result.end = 0; // 初始化结果的结束索引为0

    for (int i = 0; i < arr.size(); i++) {
        maxEndingHere += arr[i]; // 将当前元素加入当前子数组和

        if (maxSoFar < maxEndingHere) {
            maxSoFar = maxEndingHere; // 更新最大和
            start = s; // 更新起始索引
            end = i; // 更新结束索引
        }

        if (maxEndingHere < 0) {
            maxEndingHere = 0; // 如果当前子数组和为负数,重新开始计算子数组和
            s = i + 1; // 更新起始索引
        }
    }

    result.maxSum = maxSoFar; // 将最大和存入结果对象
    result.start = start; // 将起始索引存入结果对象
    result.end = end; // 将结束索引存入结果对象

    return result; // 返回结果对象
}

int main() {
    std::vector<double> arr = {-2.0, 1.0, -3.0, 4.0, -1.0, 2.0, 1.0, -5.0, 4.0};
    Result result = findMaxSubarray(arr);

    std::cout << "最大连续子数组的和为 " << result.maxSum << std::endl;
    std::cout << "起始索引: " << result.start << std::endl;
    std::cout << "结束索引: " << result.end << std::endl;

    return 0;
}

算法思想:

  1. Kadane算法的核心思想是动态规划。我们通过一次遍历数组就能找到最大子数组和。
  2. 我们维护两个变量:
    • maxSoFar:到目前为止找到的最大子数组和
    • maxEndingHere:以当前元素结尾的最大子数组和
  3. 对于每个元素,我们有两个选择:
    • 将当前元素加入到现有的子数组中
    • 开始一个新的子数组
  4. 如果maxEndingHere变为负数,我们就重置它为0,因为没有理由保留一个负的子数组和。
  5. 我们还跟踪最大子数组的起始和结束索引。

代码解释:

  1. 我们定义了一个Result结构来存储最大和及其对应的起始和结束索引。
  2. findMaxSubarray函数实现了Kadane算法:
    • 初始化maxSoFar为最小的可能值,maxEndingHere为0。
    • 遍历数组,更新maxEndingHeremaxSoFar
    • 当找到一个新的最大和时,更新起始和结束索引。
    • 如果maxEndingHere变为负数,重置它并更新潜在的新起始索引。
  3. main函数中,我们展示了如何使用这个算法。

这个算法的时间复杂度是O(n),其中n是数组的长度,因为我们只需要遍历数组一次。空间复杂度是O(1),因为我们只使用了常数额外空间。

这个算法非常高效,它能在一次遍历中找到最大子数组和,而不需要考虑所有可能的子数组(这将需要O(n^2)的时间复杂度)。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值