最大子序列和问题的解

关于最大子序列和问题的解在书中一共看到了四种方法,前两种方法均是通过比较所有可能的子序列的和求解,而第三种采用递归方法算是有了较大的改进,而第四种更是nice。

下面是对每一种方法的实现

第一种时间复杂度是O(N^3):

/* 
*Author:gyh
*Date:20141225
*/
#include<stdio.h>
#include<math.h>
void maxsubsequencesum(const int a[], int n);
int main(void){
	int a[8] = { 4, -3, 5, -2, -1, 2, 6, -2};
	maxsubsequencesum(a, 8);
	return 0;
}

void maxsubsequencesum(const int a[], int n){
	int thissum = 0;
	for(int i = 0; i < n; i++){
		for(int j = i; j < n; j++){
			int sumnow = 0;
			for(int k = i; k < j; k++){
				sumnow += a[k];
			}
			if(thissum < sumnow){
				thissum = sumnow;
			}
		}
	}
	printf(" %d\n", thissum);
}

第二种时间复杂度是O(n^2):

/*
*Author:gyh
*Date:20141225
*Version:2.0
*/
#include<stdio.h>
int main(void){
	void maxsubsequencesum(const int a[], int n);
	int a[] = { 4, -3, 5, 2, -1, -2, 6, -2};
	maxsubsequencesum(a, 8);
	return 0;
}
void maxsubsequencesum(const int a[], int n){
	int thissum = 0;
	for(int i = 0; i < n; i++){
		int sumnow = 0;
		for(int j = i; j < n; j++){
			sumnow += a[j];
			if(sumnow > thissum)  thissum = sumnow ;
		}
	}
	printf(" %d\n", thissum);
}

第三种时间复杂度是O(nlogn):

/*
*Author:gyh
*Date:20141225
*Version:3.0
*/
#include<stdio.h>
int maxsum(const int a[], int left, int right);
void maxsubsequencesum(const int a[], int n);
int main(void){
	int a[] = { 4, -3, 5, -2, -1, 2, 6, -2};
	maxsubsequencesum(a, 8);
	return 0;
}
void maxsubsequencesum(const int a[], int n){
	printf(" %d\n", maxsum(a, 0, n-1));
}

int maxsum(const int a[], int left, int right){
	int leftbordersum, rightbordersum;
	int maxleftsum, maxrightsum;
	int maxleftbordersum, maxrightbordersum;
	int center;
	if(left == right){					//如果只含有一个数则返回
		if(a[left] > 0){
			 return a[left];
		}
		else{
			 return 0;
		}
	}
	center = (left + right)/2;

	maxleftbordersum = 0;
	maxrightbordersum = 0;
	leftbordersum = 0;
	rightbordersum = 0;

	for(int i=center; i >= left; i--){			//计算左边界和的最大值
		leftbordersum += a[i];
		if (maxleftbordersum < leftbordersum){
			maxleftbordersum = leftbordersum;
		}
	}
	printf("maxleftbordersum = %d ", maxleftbordersum);
	
	for(int i=center+1; i <= right; i++){			//计算右边界和的最大值
		rightbordersum += a[i];
		if(maxrightbordersum < rightbordersum){
			maxrightbordersum = rightbordersum;
		}
	}
	printf("maxrightbordersum = %d\n", maxrightbordersum);

	maxleftsum = maxsum(a, left, center);
	maxrightsum = maxsum(a, center + 1, right);

	printf("maxleftsum = %d maxrightsum = %d\n", maxleftsum, maxrightsum);

	if(maxleftbordersum + maxrightbordersum < maxleftsum){
		/*如果左右边界的最大值之和大于左右最大子序列和则返回左右边界最大值和否则返回最大值*/
		  if(maxleftsum > maxrightsum) return maxleftsum;
		  else if(maxleftbordersum + maxrightbordersum < maxrightsum) return maxrightsum;
	
	}else if(maxleftbordersum + maxrightbordersum < maxrightsum) return maxrightsum;
	else return maxleftbordersum + maxrightbordersum;
}

 
第四种时间复杂度为O(n)

/*
*Author:gyh
*Date:20141225
*Version:4.0
*/
#include <stdio.h>
int main(void){
  int a[] = { 4, -3, 5, -2, -1, 2, 6, -2};
  int thissum, sumnow = 0;
  thissum = 0;
  for(int i = 0; i < 8; i++){
    sumnow += a[i];
    if(thissum < sumnow) thissum = sumnow;
    else if(sumnow < 0) sumnow = 0;
  }
  printf(" %d\n", thissum);
  return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值