最长平台问题 C实现

此问题来自《C语言名题精选百则》

问题1.1最长平台(plateau.c)

    已知一个从小到大排序的数组,这个数组中的一个平台(plateau)是连续的一串值相同的元素,并且这一串元素不能再延伸,例如,在1,2,2,3, 3, 3, 4 ,5 ,5 ,6中1, 2.2, 3.3.3, 4, 5.5, 6都是平台,编写一个程序接收一个数组,把这个数组中平台最长的平台找出来,在上面的例子中,3,3,3就是数组中最长的平台。

需要考虑一下几点:

1.使用变量越少越好;

2.能否把数组的元素每一个都只查一次就得到结果?

3.程序语句越少越好。

我的想法是,用一个变量保存最长平台数值,再用一个变量保存最长平台长度,函数要返回这两个数值,就得用结构体

typedef struct{

    int data;

    int num;

}plateau;

如何计算平台长度?

当当前数值和前一个数值不相等时,统计前一个平台的长度,将这个长度和最长平台相比,如果大于最长平台,则将最长平台的数值和长度都保存为上一个平台的数值和长度,否则,当前值和前一个值相等,则将平台的长度+1;

if (arr[i] != arr[i-1] && length > max.num){

     max.data = arr[i-1];

     max.num = length;

}else{

    length++;

}

这种方式导致数组里最后一个值和倒数第二个值比较完以后,最后一个平台没有进行和max.num的比较,因此比较麻烦,还要在最后判断最后一个平台的长度,看了答案以后,觉得答案好简单,复杂度很低,也是o(n),并且变量值很少,因为答案上只返回了长度而没有返回长度值,因此我自己修改为返回两个值。

代码如下:

#include <stdio.h>
#include <stdlib.h>
#define NUM 12
typedef struct{
    int data;
    int length;
}plate;
plate longest_plateau(int a[],int n)
{
	plate longest;
	longest.length = 1;
	int data;
	int i;
	for(i=1;i<n;i++){
	    if(a[i] == a[i-longest.length]){
		    longest.length ++;
		    longest.data = a[i];
		}
	}
	return longest;
}
int main(int argc,char *argv[])
{
	int i;
	plate p;
	int arr[NUM] = {1,2,2,3,3,4,4,5,5,6,6,6};
	printf("The array is:");
	for(i=0;i<NUM;i++){
	    printf("%d ",arr[i]);
	}
	p=longest_plateau(arr,NUM);
	printf("\nThe max plateau is:");
	for(i=0;i<p.length;i++){
		printf("%d ",p.data);
	}
	getchar();
	return 0;

}


运行过程:

longest.length = 1

i=1,      a[i] = a[1] =2 ,

             a[i-length] = a[1-1] = a[0] = 1,

             a[i] != a[i-longes.tlength]  ,  if里的语句不执行,longest.ength = 1

i=2,      a[i] = a[2] =2;

             a[i-length] = a[2-1] = a[1] = 2,

             a[i] = a[i-longes.tlength]  ,  if里的语句执行,longest.length = longest.length +1 = 2; longest.data = a[i] = a[2] = 2;

i=3,      a[i] = a[3] = 3;

             a[i-length] = a[3-2] = a[1] = 2,

             a[i] != a[i-longes.tlength]  ,  if里的语句不执行,longest.length = 2;

i=4,      a[i] = a[4] = 3;

             a[i-length] = a[4-2] = a[2] = 2,

             a[i] != a[i-longes.tlength]  ,  if里的语句不执行,longest.length = 2;

i=5,      a[i] = a[5] = 4;

             a[i-length] = a[5-2] = a[3] = 3,

             a[i] != a[i-longes.tlength]  ,  if里的语句不执行,longest.length = 2;

i=6,      a[i] = a[6] = 4;

             a[i-length] = a[6-2] = a[4] = 3,

             a[i] != a[i-longes.tlength]  ,  if里的语句不执行,longest.length = 2;

i=7,      a[i] = a[7] = 5;

             a[i-length] = a[7-2] = a[5] = 4,

             a[i] != a[i-longes.tlength]  ,  if里的语句不执行,longest.length = 2;

i=8,      a[i] = a[8] = 5;

             a[i-length] = a[8-2] = a[6] = 4,

             a[i] != a[i-longes.tlength]  ,  if里的语句不执行,longest.length = 2;

i=9,    a[i] = a[9] = 6;

             a[i-length] = a[9-2] = a[7] = 5,

             a[i] != a[i-longes.tlength]  ,   if里的语句不执行,longest.length = 2;

i=10,  a[i] = a[10] = 6;

             a[i-length] = a[10-2] = a[8] = 5,

             a[i] != a[i-longes.tlength]  ,   if里的语句不执行,longest.length = 2;

i=11,  a[i] = a[11] = 6;

             a[i-length] = a[11-2] = a[9] = 6,

             a[i] != a[i-longes.tlength]  ,   if里的语句执行,longest.length = longest.length +1 = 3; longest.data = a[i] = a[11] = 6.

运行结果


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值