自己编的求最大子段和算法C++代码

本文介绍了一种使用C++实现的求最大子段和的方法,通过对数组进行正向和反向累加求和,找到最大子段和及其对应的起始和结束下标。该方法的算法复杂度为O(2n),介于动态规划法和蛮力法之间。

自己编的求最大子段和方法C++代码

对数组arr[n]分别进行正向和反向累加求和,并求两过程的最大值sum1和sum2,并记录最大时的下标,正向为记为a,逆向记为b,则arr[b]至arr[a]的和即为所求。
其算法复杂度为O(2n),高于动态规划法,低于蛮力法。

#include <iostream>
#include <stdlib.h>

using namespace std;

int *maxSum(int a[], int len){

    int sum = 0;
    int max = a[0];
    int i, *index;

    index = (int *)malloc(sizeof(int)*3);   //申请空间

    for(i=0; i<len; i++){   //从a[0]开始累加,找sum最大情况
        sum+=a[i];
        if(max<sum){
            max=sum;
            index[1] = i;   //最大字段的右端下标
        }
    }
    max = a[len-1];
    for(i=len-1; i>=0; i--){    //从a[i]倒序累加,找sum最大情况
        sum+=a[i];
        if(max<sum){
            max=sum;
            index[2] = i;   //最大字段的左端下标
        }
    }
    max = 0;
    //cout << "index[1]:" << index[1] << endl << "index[2]:" << index[2] << endl;
    for(i=index[2]; i<=index[1]; i++)
        max+=a[i];	//最大子段和

    for(i=index[2]; i<=index[1]; i++){
        if(max<sum){
            cout << "一次求解失败,需要递归求解" << endl;
            return 0;
        }
        index[0] = max;
    }

    return index;
}
int main()
{
    int a[6] = {-20, 11, -4, 13, -5, -2};
    int *max;

    
    max = maxSum(a, 6);

    Q

    cout << "最大子段和是:" << max[0] << endl;
    cout << "Start:" << max[2]+1 << endl;
    cout << "End:" << max[1]+1 << endl;
    return 0;
}

注:这种方法是我无意间想出来的,能力有限,不会证明,故不敢称其为算法;这个想法想必前人已经提出来过,其正确性或许已被证明,博主才疏学浅,不得知。

### 最大问题的C++实现 最大问题是算法领域中的经典问题,其目标是从一个整数数组中找到连续数组的最大。以下是几种常见的算法实现方式,包括蛮力法、分治法动态规划法。 #### 蛮力法 蛮力法通过三重循环枚举所有可能的,并计算它们的以找到最大值。这种方法的时间复杂度为 \(O(n^3)\),但可以通过优化降低到 \(O(n^2)\) [^1]。以下是一个优化后的 C++ 实现代码: ```cpp #include <iostream> #include <vector> using namespace std; int main() { int n, max_sum = INT32_MIN; cin >> n; vector<int> a(n); for (int i = 0; i < n; ++i) cin >> a[i]; for (int i = 0; i < n; ++i) { int sum = 0; for (int j = i; j < n; ++j) { sum += a[j]; if (sum > max_sum) max_sum = sum; } } cout << max_sum << endl; return 0; } ``` #### 分治法 分治法将数组分为左右两部分,递归地解左右两部分的最大,并计算跨越中间点的最大。最终结果为这三者中的最大值。分治法的时间复杂度为 \(O(n \log n)\) [^2]。以下是一个 C++ 实现代码: ```cpp #include <iostream> #include <vector> #include <algorithm> using namespace std; int find_max_crossing_subarray(const vector<int>& a, int left, int mid, int right) { int left_sum = INT32_MIN, sum = 0; for (int i = mid; i >= left; --i) { sum += a[i]; if (sum > left_sum) left_sum = sum; } int right_sum = INT32_MIN, sum2 = 0; for (int i = mid + 1; i <= right; ++i) { sum2 += a[i]; if (sum2 > right_sum) right_sum = sum2; } return left_sum + right_sum; } int divide_and_conquer(const vector<int>& a, int left, int right) { if (left == right) return a[left]; int mid = (left + right) / 2; int left_max = divide_and_conquer(a, left, mid); int right_max = divide_and_conquer(a, mid + 1, right); int cross_max = find_max_crossing_subarray(a, left, mid, right); return max({left_max, right_max, cross_max}); } int main() { int n; cin >> n; vector<int> a(n); for (int i = 0; i < n; ++i) cin >> a[i]; cout << divide_and_conquer(a, 0, n - 1) << endl; return 0; } ``` #### 动态规划法 动态规划是解决最大问题的最优方法之一,其核心思想是利用递推公式 \(C[i] = \max(C[i-1] + a[i], a[i])\) 来计算以每个位置结尾的最大。最终答案为所有 \(C[i]\) 中的最大值。动态规划的时间复杂度为 \(O(n)\) [^3]。以下是一个 C++ 实现代码: ```cpp #include <iostream> #include <vector> #include <algorithm> using namespace std; int main() { int n, max_sum = INT32_MIN, current_sum = 0; cin >> n; vector<int> a(n); for (int i = 0; i < n; ++i) cin >> a[i]; for (int i = 0; i < n; ++i) { current_sum = max(a[i], current_sum + a[i]); max_sum = max(max_sum, current_sum); } cout << max_sum << endl; return 0; } ``` ### 总结 上述三种方法分别对应了不同时间复杂度的解决方案。蛮力法适合理解问题的本质,但效率低下;分治法提供了较好的平衡;动态规划则是最优解法。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值