浙江大学mooc的数据结构_课后习题01-复杂度2 Maximum Subsequence Sum

博客详细介绍了如何解决浙江大学MOOC数据结构课程中的课后习题——复杂度2 Maximum Subsequence Sum。内容涉及最大子列和的计算,以及在特殊情况下如何确定最大子序列的起始和结束位置,特别是当存在0或者全为负数的情况。文章强调了最大子序列的第一个元素可以是0但不能是负数,最后一个元素不能为0或负数,并给出了相应的C语言实现代码。
摘要由CSDN通过智能技术生成

题目基本要求:

  • 输出最大子列和结果

  • 输出最大子列的头和尾(若结果不唯一,要输出出现最大子列最早的那两个数字)

  • 若全为负数则输入整个数列的首个数字和末尾数字(下面用左标和右标表示)

  • 若为单个数,则左右都取这个数
    注意:这里有个坑点(有一段0在最大的子列前面的的话,头要取到0)举个例子:0 0 0 0 1 2 3 4 0 -10 结果是:10 0 4

    最大子列的特点:最大子列中第一个数可以为0,但是不可以为负数,而最后一个数字不可以为0(题意:取出现最早的),也不能为负数,凭借这个我们可以在最后判断一下一些特殊情况。

代码如下:

#include<stdio.h>
int main(){
	int tip = 0; //用来判断当下是否需要改变左列首位记录
	int maxleft = -1;//用于保留最大子列的最左的数字
	int K = 0;
	long this_num = 0,max_num = 0; //记录当下值和最大值
	int left = -1,right = 0; /*记录左标和右标
							左标是根据this_num为0的时候进行改值,而右标是根据取到最大子列的时候进行改值
							左标要不断的改,所以要有变量记录最大子列的左标*/
		scanf("%d",&K); 
	for(int i = 0; i < K; i++) {
		int num = 0;
		scanf("%d",&num);
		
		if(i == 0) left = maxleft = num; //将最大左标和左标都取首位
		if(i == K-1 && right == 0 && left < 0)//根据上述最大子列特征
			right = num;					//到最后一步的时候判断一下,右标是否为0(根本没变过值),和left是否小于0
											//这个情况是为了防止所有的数字都为负数							
		if(this_num == 0 && num >= 0 && tip == 0){	
		//注意左位可取0,tip是防止0无法赋值给left(若没有tip提示,上述例子的结果是 10 1 4)
			left = num;
			tip = 1;	//改变tip值是为了停止改变左值,说明先处于累加求和的状态。
		}
			
		this_num += num;  //累加
		
		if(this_num > max_num) {	//若进入了这个判断体,就要保留最大值,和最大子列左标和右标
			max_num = this_num;			
			right = num;
			maxleft = left;
		} else if(this_num < 0) {  //若进入了这个判断体,就要将当下和变为0,和准备记录新的左标
			this_num = 0;
			tip = 0;
		}
			
			
	}
	//最后是为了防止只有一个零,而其余全是负数的时候,这时候左右标都得取0(有特性可知,左标可以被赋值到0,但右标不可)
	if(left == 0 && right == 0) {
		maxleft = right = 0	;	
	}
	printf("%ld %d %d",max_num,maxleft,right);
	
}

数据结构还是很有意思的,fighting!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值