最大子数组和

来源:互联网 发布:table js表格数据合计 编辑:程序博客网 时间:2024/05/16 09:26

最大子数组和

问题描述:

​ 求一个有序序列的最大子数组和,即求的这个数组的子数组中和最大的数组。

解决问题方法:

1、暴力枚举:

​ 利用简单的循环枚举出所有的可能性进行比较得到最终的结果。

/***   最大子数组求解问题(L为线性表)*   问题描述:已知一个数组序列L,求出该数组的最大子数组,即数组元素之和最大的子数组*/typedef int type;/** *  用来保存所求的的子数组的起始位置 */typedef struct sub_array{    int begin;    int end;    type result;};/** *  方法一:     *  暴力求解:   遍历该数组的所有子数组的和之后并且进行比较 *  时间复杂度:O(n^2) *  空间复杂度:O(n) */struct sub_array max_array(type *L, int len){    int i = 0, j = 0,k = 0;    type result = 0;    struct sub_array tmp;    tmp.result = 0;    for (i = 0; i < len; i++)    {        for (j = i; j < len; j++)        {            result += L[j];                             if (tmp.result < result)            {                tmp.result = result;                tmp.begin = i;                tmp.end = j;            }        }        result = 0;    }    return tmp;}

2、分治思想

​ 利用分治思想将原序列分解为多个子序列直到问题可以小到可以直接解决,然后再将子问题求解结果合并得到最终的结果。但是这里又和相关的归并问题不同,因为多路归并只会将问题分解求解子问题,但是相关的子数组可能出现在跨越界限的数组中,因此需要添加特殊的函数进行处理,其他和二路归并基本相同。

示意图

​ 图片中括号内是取得该最大值的起始点和终点的下标,之所以为理想效果图是因为数组本身从0开始而实际上我们运算时用的是符合人的基本的思想规律的云算方式,因此实际运行上会错开一位,但是并不影响实际的效率和结果。

这里写图片描述

#define MAX_INT ((int)((unsigned)(-1)>>1))              //最大整数#define MIN_INT ((int)(~MAX_INT))                      //最小整数/***   最大子数组求解问题(L为线性表)*   问题描述:已知一个数组序列L,求出该数组的最大子数组,即数组元素之和最大的子数组*/typedef int type;/** *  用来保存所求的的子数组的起始位置 */struct sub_array{    int begin;    int end;    type result;};/** *  分治思想: *  时间复杂度:O(nlog_2_n) *  空间复杂度:O(1) *//** *  因为分治算法会将数组分解为多个小部分进行求解,而最大子数组也可能出现在跨越分界点,因此单独列出来进行分析 */struct sub_array max_cross(type *L, int low, int mid, int high){    struct sub_array sub;                                   //用来存放取得的最大子数组的相关数据    int i = 0;    int result = 0;    int right_result = 0;    sub.result = MIN_INT;    for (i = mid; i >= low; i--)                                //求解中点左边的子数组的最大子数组    {        result += L[i];        if (result > sub.result)        {            sub.result = result;            sub.begin = i;        }    }    result = MIN_INT;    for (i = mid + 1; i <= high; i++)    {        right_result += L[i];        if (result < right_result)        {            result = right_result;            sub.end = i;        }    }    sub.result += result;    return sub;}struct sub_array max_sub(type *L, int low, int high){    if (high == low)    {        struct sub_array sub;        sub.begin = low;        sub.end = high;        sub.result = L[low];        return sub;    }    int mid = (low + high) / 2;    struct sub_array right_sub;    struct sub_array left_sub;    struct sub_array sub_cross;    right_sub = max_sub(L, low, mid);    left_sub = max_sub(L, mid + 1, high);    sub_cross = max_cross(L, low, mid, high);    //比较三者的最大值进行返回    if (right_sub.result > left_sub.result && right_sub.result > sub_cross.result)    {        return right_sub;    }    else if (left_sub.result > right_sub.result && left_sub.result > sub_cross.result)    {        return left_sub;    }    else    {        return sub_cross;    }}
0 0