求数组最大子段和的常用算法

1 篇文章 0 订阅
1 篇文章 0 订阅
/*
* 求数组的最大子段和
*/
package acm;
import static java.lang.System.out;

import java.io.BufferedInputStream;
import java.util.Scanner;

public class Acm1003 {
	public int bestStar = 0; // 起始下标
	public int bestEnd = 0;  // 终止下标
	
        /*动态规划*/
	public  int MaxSum1(int[] a){
		int sum = 0;
		int b = 0;
		for(int i=0; i<a.length; i++){
			if( b>0 ){
				b += a[i];
			}else{
				b = a[i];
			}
			if( b>sum ) {
				sum = b;
			}
		}
		return sum;
	}

	/*一般算法*/
	public  int MaxSum2(int[] a){
		int sum = 0;
		for(int i=0; i<a.length; i++){
			for(int j=i; j<a.length; j++){
				int thissum = 0;
				for(int k=i; k<=j;k++){
					thissum += a[k];
				}
				if(thissum > sum){
					sum = thissum;
					this.bestStar = i;
					this.bestEnd = j;
				}
			}
		}
		return sum;
		
	}
	/*一般算法的优化*/
	public  int MaxSum3(int[] a){
		int sum = 0;
		for(int i=0; i<a.length; i++){ // 可以将 for 判断条件 改为 a[i]>0&&i<a.length 以减少运算量
			int thissum = 0;
			for(int j=i; j<a.length; j++){
				thissum += a[j];
				if(thissum > sum){
					sum = thissum;
					this.bestStar = i;
					this.bestEnd = j;
				}
			}
		}
		return sum;
	}
	/*分治算法*/
	public int MaxSubSum(int[] a, int left, int right ){
		int sum = 0;
		if(left == right){
			sum = ( a[left]>0 ? a[left] : 0 );
		}else{
			int center = ( left+right ) / 2;
			int leftsum = MaxSubSum(a,left,center);
			int rightsum = MaxSubSum(a,center+1,right);
			int sL = 0;
			int lefts = 0;
			for(int i=center; i>=left; i--){
				lefts += a[i];
				if(lefts>sL) sL=lefts;
			}
			int sR = 0;
			int rights = 0;
			for(int i=center+1; i<=right; i++){
				rights += a[i];
				if(rights>sR) sR=rights;
			}
			sum = sL + sR;
			if(sum<leftsum) sum=leftsum;
			if(sum<rightsum) sum=leftsum;
		}
		return sum;
	}
	public int MaxSum4(int[] a){
		return MaxSubSum(a,0,a.length-1);
	}
	
	public static void main(String[] args) {
		Scanner cin =  new Scanner(new BufferedInputStream(System.in));
		int[] a = {-2,11,-4,13,-5,-2};
		Acm1003 acm10031 = new Acm1003();
		out.println("动态规划 :"+acm10031.MaxSum1(a));
		Acm1003 acm10032 = new Acm1003();
		out.println("一般算法: "+acm10032.MaxSum2(a)+"\t起始:"+acm10032.bestStar+" 终点 "+acm10032.bestEnd);
		Acm1003 acm10033 = new Acm1003();
		out.println("一般算法优化: "+acm10033.MaxSum2(a)+"\t起始:"+acm10033.bestStar+" 终点 "+acm10033.bestEnd);	
		out.println("分治算法:" +acm10033.MaxSum4(a));
	}
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值