最大连续子数组

最大连续子数组:

 

  1. 暴力求解最大连续子数组

 

代码:

#include <iostream>

#include <cstdio>

using namespace std;

 

int main()

{

   int A[8] = { -6, 10, -5, -3, -7, -1, -1 };

   int array_length = sizeof(A) / sizeof(A[0]);//数组大小

   int sum = -10000;//记录子数组的和

   int low;//记录子数组的底

   int height;//记录子数组的高

   for (int i = 0; i < array_length; i++)

    {

       for (int j = i ; j < array_length; j++)

       {

           int subarraysum=0;//所遍历出来的子数组的和

           //计算遍历的子数组之和

           for (int k = i; k <= j; k++)

           {

                subarraysum += A[k];

           }

           //找出最大的子数组

           if (subarraysum>sum)

           {

                sum = subarraysum;

                low = i;

                height = j;

           }

       }

    }

   printf("%d  %d  %d\n", low, height,sum);//将结果打印出来

   getchar();

 

   return 0;

}

 

2.分治法(算法导论)

 

代码:

#include <limits.h>

#include <stdio.h>

struct PSum{

   int low;

   int high;

   int sum;

};

 

 

//跨越中点的最大子数组,这是最特殊也是最好的找的一段区间

PSum FIND_MAX_CROSSING_SUBARRAY(int *A ,int low , int mid , int high)

{

   int i;

   int sum=0;

   int right_sum=INT_MIN,left_sum=INT_MIN;

   int max_left=0,max_right=0;

 

//先找左边最大的,再找右边最大的,直接暴力找就好了

   for(i=mid ; i>=low ; i--){

       sum+=A[i];

       if(sum>left_sum){

           left_sum=sum;

           max_left=i;

       }

    }

 

   sum=0;

   for(i=mid+1 ; i<=high ; i++){

       sum+=A[i];

       if(sum>right_sum){

           right_sum=sum;

           max_right=i;

       }

    }

 

   PSum ps;

   ps.low = max_left;

    ps.high= max_right;

   ps.sum = left_sum + right_sum;

   return ps;

}

//还是递归的思想,全部都交给中间段来找,如何进行比较大小

PSum FIND_MAXIMUM_SUBARRAY(int *A , int low, int high)

{

   if (low == high)

    {

       PSum ps;

       ps.low = low;

       ps.high = high;

       ps.sum = A[low];

       return ps;

    }

   else{

       int mid = (low + high) / 2;

       PSum left = FIND_MAXIMUM_SUBARRAY(A, low, mid);

       PSum right = FIND_MAXIMUM_SUBARRAY(A, mid + 1, high);

       PSum cross = FIND_MAX_CROSSING_SUBARRAY(A, low, mid, high);

       if (left.sum >= cross.sum && left.sum >= right.sum){

           return left;

       }

       else if (right.sum >= left.sum && right.sum >= cross.sum){

           return right;

       }else{

           return cross;

       }

    }

 

}

 

int main()

{

   int A[8] = {-6, 10, -5, -3, -7, -1, -1};

   PSum result;

   result = FIND_MAXIMUM_SUBARRAY(A, 0, 7);

   printf("%d %d %d\n", result.low , result.high , result.sum);//将结果打印出来

   //getchar();

   return 0;

}

 

 

 

 

 

3.在线算法

 

代码:

//在线法求最大子数组和问题

int  main()

{

    int A[8] = { -6, 10, -5, -3, -7, -1, -1 };

    int array_length = sizeof(A) /sizeof(A[0]);//数组大小

    int sum = 0;//记录子数组的和

    int thisSum = 0;

    for (int i = 0; i < array_length; i++)

    {

        thisSum += A[i];

        if (thisSum > sum){

            sum = thisSum;

        }

//如果累加和出现小于0的情况, 

//则和最大的子序列肯定不可能包含前面的元素, 

//这时将累加和置0,从下个元素重新开始累加

        else if (thisSum < 0) {

            thisSum = 0;

        }

    }

printf("%d",sum);//将结果打印出来

return 0;

}

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值