【蓝桥云课】最大连续子段和

文章介绍了四种不同的方法来找出一个整数序列中的最大连续字段和,包括三层循环遍历、穷举所有子段起始点、动态规划以及基于当前字段和的遍历策略。每种方法都通过实例展示了计算过程,并给出了相应的运行结果,最终得出最大字段和为20。
摘要由CSDN通过智能技术生成

题目描述:给定一个序列a,求它的最大连续字段和

方法一:三层for循环遍历序列所有的字段,求出最大的字段和

public static void f1() {
	int[] a = {-2,11,-4,13,-5,2};//原始数组
	int max = -9999;//记录全局的最大连续子段和
	for(int start=0;start<a.length;start++) {
		for(int len=1;start+len<=a.length;len++) {
			int sum=0;
			for(int k=start;k<start+len;k++) {
				sum=sum+a[k];
			}
			max=Math.max(max, sum);
			System.out.printf("len=%2d a[%d-%d]sum=%2d\n",len,start,start+len,sum);
		}
	}
	System.out.println("最大子段和应该是"+max);
}

运行结果:

len= 1 a[0-1]sum=-2
len= 2 a[0-2]sum= 9
len= 3 a[0-3]sum= 5
len= 4 a[0-4]sum=18
len= 5 a[0-5]sum=13
len= 6 a[0-6]sum=15
len= 1 a[1-2]sum=11
len= 2 a[1-3]sum= 7
len= 3 a[1-4]sum=20
len= 4 a[1-5]sum=15
len= 5 a[1-6]sum=17
len= 1 a[2-3]sum=-4
len= 2 a[2-4]sum= 9
len= 3 a[2-5]sum= 4
len= 4 a[2-6]sum= 6
len= 1 a[3-4]sum=13
len= 2 a[3-5]sum= 8
len= 3 a[3-6]sum=10
len= 1 a[4-5]sum=-5
len= 2 a[4-6]sum=-3
len= 1 a[5-6]sum= 2
最大子段和应该是20

方法二:穷举所有子段的起始点

public static void f2() {
	int[] a = {-2,11,-4,13,-5,2};//原始数组
	int max = -9999;//记录全局的最大连续子段和
	for(int start=0;start<a.length;start++) {//穷举所有子段的起始点
		int sum = 0;
		for(int len=start;len<a.length;len++) {//从start开始,一直一次累计到最后
			sum=sum+a[len];
			max=Math.max(max, sum);//记录最大的那个
			System.out.printf("len=%2d a[%d-%d]sum=%2d\n",len+1,start,len+1,sum);
		}
	}
	System.out.println("最大字段和应该是"+max);
}

运行结果:

len= 1 a[0-1]sum=-2
len= 2 a[0-2]sum= 9
len= 3 a[0-3]sum= 5
len= 4 a[0-4]sum=18
len= 5 a[0-5]sum=13
len= 6 a[0-6]sum=15
len= 2 a[1-2]sum=11
len= 3 a[1-3]sum= 7
len= 4 a[1-4]sum=20
len= 5 a[1-5]sum=15
len= 6 a[1-6]sum=17
len= 3 a[2-3]sum=-4
len= 4 a[2-4]sum= 9
len= 5 a[2-5]sum= 4
len= 6 a[2-6]sum= 6
len= 4 a[3-4]sum=13
len= 5 a[3-5]sum= 8
len= 6 a[3-6]sum=10
len= 5 a[4-5]sum=-5
len= 6 a[4-6]sum=-3
len= 6 a[5-6]sum= 2
最大字段和应该是20

方法三:采用动态规划的方法, d p [ i ] = m a x dp[i]=max dp[i]=max{ d p [ i − 1 ] + a [ i ] , a [ i ] dp[i-1]+a[i],a[i] dp[i1]+a[i],a[i]},

详细过程:以a={-2,11,-4,13,-5,2}为例,
①定义存放字段和的数组dp, 大小和数组a相等;
②dp[0]=a[0]=-2,max=-9999;
③i=1,dp[1]=max(dp[0]+a[1],a[1])=max(0+11,11)=11,max=11;
④i=2,dp[2]=max(dp[1]+a[2],a[2])=max(11-4,-4)=7,max=11;
⑤i=3,dp[3]=max(dp[2]+a[3],a[3])=max(7+13,13)=20,max=20;
⑥i=4,dp[4]=max(dp[3]+a[4],a[4])=max(20-5,-5)=15,max=20;
⑦i=5,dp[5]=max(dp[4]+a[5],a[5])=max(15+2,2)=17,max=20;

public static void f3() {
	int[] a={-2,11,-4,13,-5,2};//原始数组
	int[] dp=new int[a.length];
	dp[0]=a[0];
	int max=-9999;
	for(int i=1;i<a.length;i++) {
		dp[i]=Math.max(dp[i-1]+a[i], a[i]);
		if(max<dp[i]) max=dp[i];
	}
	System.out.println(Arrays.toString(dp));
	System.out.println(max);
}

运行结果:

[-2, 11, 7, 20, 15, 17]
20

方法四:遍历数组,当前的字段和大于0,则加上当前数a[i];否则就把当前数a[i]作为字段和(即i为字段的初始起点),然后继续向后遍历,直到数组结束。

详细过程:以a={-2,11,-4,13,-5,2}为例,
i=0,nowsum=-2,max=-2;
i=1,nowsum=11,max=11;
i=2,nowsum=11-4=7,max=11;
i=3,nowsum=7+13=20,max=20;
i=4,nowsum=20-5=15,max=20;
i=5,nowsum=15+2=17,max=20;

public static void f4() {
	int[] a={-2,11,-4,13,-5,2};//原始数组
	int nowsum=0;
	int max=-9999;
	for(int i=0;i<a.length;i++) {
		if(nowsum>0) nowsum=nowsum+a[i];
		else nowsum=a[i];
		if(nowsum>max) max=nowsum;
		System.out.println(nowsum);
	}
	System.out.println(max);
}

运行结果:

-2
11
7
20
15
17
20
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CS_木成河

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值