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
解题思路
-
比较不同递增组的递增次数,
a. 将输入的数遍历完之后再比较,因此需采用数组
b. 只找出最大值,单一变量可以完成
-
储存实时的最大递增序列
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;
}
我的收获
面对即时的应用时,先尽量往简单的方面去思考
但是平时可以多想想怎么扩充思路,因为有可能下一次就能用上
我们学的并不是特别难,不用想得太复杂