python substring 求和_算法设计--在数组中找求和最大的连续子串

问题:输入具有n个整数的向量arr,输出向量的任意连续子向量和的最大值

特殊情况(1、当向量都为正数时,为整个向量

2、当向量都为负数时,为0,即空子串

)

1、O(n2)的算法 (循环对所有情况进行遍历)

48304ba5e6f9fe08f3fa1abda7d326ab.png

1 #include

2 #define max(a,b) ((a>b)?a:b)

3 #define max3(a,b,c) ((a>b)?((a>c)?a:c):((b>c)?b:c))

4

5 int find1(int arr[], int n){

6 int i,j,sum,maxsofar;

7 maxsofar = 0;

8

9 for(i=0; i

10 sum = 0;

11 for(j=i; j

12 sum += arr[j];

13 maxsofar = max(sum, maxsofar);

14 }

15 }

16 return maxsofar;

17 }

48304ba5e6f9fe08f3fa1abda7d326ab.png

其中有个小细节就是 注意sum(i, j-1) 和 sum(i, j)的关系,不要每次在求和的时候从头(i的位置)开始,那样会使复杂度变为O(n3)

2、O(nlogn)算法

基于分治原理的算法:首先将n的原问题划分为大小基本相等的两个子问题,我们分别称为a和b子问题,可以递归找出a和b问题的最大子向量,称为maxa 和 maxb。

但他们两个之间的最大值不一定使我们求得n问题的最优解,还有一种可能是跨越a和b的边界,我们称之为c,c情况的最优解为maxc。

那么问题变成了如何求解maxc?

我们可以发现,maxc中在a的部分为a中包括a的右边界的最大值,maxc中在b的部分为b中包括b的左边界的最大值,因此可以在O(N)的时间内算出maxc

因此得到T(N) = 2T(N/2) + O(N)

推导得到T(N) = O(nlogn)

48304ba5e6f9fe08f3fa1abda7d326ab.png

1 int find2(int arr[], int s_p, int e_p){

2 int m, sum, i, maxsofar, lmaxsofar, rmaxsofar;

3 maxsofar = 0;

4

5 if(s_p == e_p){

6 return maxsofar;

7 }

8 else if(s_p == e_p){

9 return max(arr[s_p],0);

10 }

11 else{

12 m = (s_p + e_p) / 2;

13

14 lmaxsofar = 0;

15 sum = 0;

16 for(i=m; i>=s_p; i--){

17 sum += arr[i];

18 lmaxsofar = max(sum, lmaxsofar);

19 }

20

21 rmaxsofar = 0;

22 sum = 0;

23 for(i=m+1; i<=e_p; i++){

24 sum += arr[i];

25 rmaxsofar = max(sum, rmaxsofar);

26 }

27

28 return max3(lmaxsofar+rmaxsofar,find2(arr, s_p, m), find2(arr, m+1, e_p));

29 }

30 }

48304ba5e6f9fe08f3fa1abda7d326ab.png

3、O(n)算法

先上代码,代码非常简短,理解起来比较困难,但是执行效率非常高

48304ba5e6f9fe08f3fa1abda7d326ab.png

1 int find3(int arr[], int n){

2 int i,maxsofar,maxendinghere;

3 maxsofar = 0;

4 maxendinghere = 0;

5

6 for(i=0; i

7 maxendinghere = max(maxendinghere + arr[i], 0);

8 maxsofar = max(maxsofar, maxendinghere);

9 }

10

11 return maxsofar;

12 }

48304ba5e6f9fe08f3fa1abda7d326ab.png

假设我们已经解决了x[0,n-1]的问题,利用分治算法的原理:前i个元素中,最大总和子数组要么在前i-1个元素中,要么其结束位置在i处。

分析其结束为止在i处的情况,那么子向量中除去i处的元素组成的子向量一定是x[0,i-1]中结束位置为i-1的最大子向量。

看代码中的关键变量为maxendinghere:在循环语句的第一个赋值语句之前,maxendinghere是结束位置为i-1的最大子向量的和;赋值语句将其修改为结束位置为i的最大子向量的和。若加上x[i]后结果依然为正值,则结束位置在i的最大子向量值就为maxendinghere+x[i],如果为负值,则重置为0。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值