数据结构PTA-线性表-2-7-4

2-7-4 最长递增子序列

题目描述:

给定一个顺序存储的线性表,请设计一个算法查找该线性表中最长的连续递增子序列。例如,(1,9,2,5,7,3,4,6,8,0)中最长的递增子序列为(3,4,6,8)。

输入格式:

输入第1行给出正整数n(≤105);第2行给出n个整数,其间以空格分隔。

输出格式:

在一行中输出第一次出现的最长连续递增子序列,数字之间用空格分隔,序列结尾不能有多余空格。

输入样例:

15
1 9 2 5 7 3 4 6 8 0 11 15 17 17 10

输出样例:

3 4 6 8

解题思路

  1. 比较不同递增组的递增次数,

    a. 将输入的数遍历完之后再比较,因此需采用数组

    b. 只找出最大值,单一变量可以完成

  2. 储存实时的最大递增序列

    a. 用单一变量储存数字开始时的索引

    b.用数组储存每一个递增数列的索引

解题难点及方法

实际动手写代码时,会发现使用了特别多的数组,怎么简化?

方法一(也是我考试的时候想出来的新办法): 在比较次数的时候可以通过count来直接索引到递增序列

=>最好的储存结构是 仅仅采用一个“二维数组” ,num[n][count],n用来保存元素,count用来计数连续递增长度。

不过,代码写出来有错误,于是我这道题0分haha

方法二(也是比较简单,容易想到的方法): 用一个一维数组来储存元素,通过单一变量maxlen的替换来寻找最大递增次数,通过思考可以发现递增序列的起始下标就是

​ 递增序列的最后一个元素的下标-递增长度(递增次数)

细节注意

无论如何 起始 len = 1 同时注意题目条件 结尾不要有多余的空格

代码(法二)实现

所需变量:一个一维数组,一个计数变量len,一个计数变量的最大值maxlen, 最大递增序列的起始下标k

#include <stdio.h>
#include <stdlib.h>

void Find(int *arr, int n){
    int i = 0,len = 1,maxlen = 1,k = 0;
    for(i = 1;i < n ;i++){
        if(arr[i] > arr[i-1]){
            len++;
        }else{
            if(len > maxlen){
                maxlen = len;
                k = i - len ;
            }
            len = 1;//重新开始,len置为初始值1
        }
    }
 // 循环结束后的检查,确保处理数组结尾处的递增序列   
    if (len > maxlen) {
        maxlen = len;
        k = n - maxlen;
    }

    
    for(i = k;i < k+maxlen;i++){//k+maxlen=递增数组的最后一个元素
        printf("%d",arr[i]);
        if(i<maxlen+k - 1){
            printf(" ");//不要有多余空格
        }
    }
}

    int main(){
    int n, i;
    scanf("%d",&n);
    int *arr = (int *)malloc(n*sizeof(int));//指针动态分配空间更方便

    for(i = 0; i < n; i++){
    scanf("%d",&*(arr+i));
    }
    Find(arr,n);
    free(arr);//记得释放
    return 0;

}

我的收获

面对即时的应用时,先尽量往简单的方面去思考

但是平时可以多想想怎么扩充思路,因为有可能下一次就能用上

我们学的并不是特别难,不用想得太复杂

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值