给定一个顺序存储的线性表,请设计一个算法查找该线性表中最长的连续递增子序列。例如,(1,9,2,5,7,3,4,6,8,0)中最长的递增子序列为(3,4,6,8)。
输入格式:
输入第1行给出正整数n(≤10
5
);第2行给出n个整数,其间以空格分隔。
输出格式:
在一行中输出第一次出现的最长连续递增子序列,数字之间用空格分隔,序列结尾不能有多余空格。
输入样例:
15
1 9 2 5 7 3 4 6 8 0 11 15 17 17 10
输出样例:
3 4 6 8
我的分析
先记录一下第一个序列的位置,比如:1 9 2 5 7 3 4 6 8 0 11 15 17 17 10中,我先记下位置pos = k ;
(此时k=0,所以第一个序列位置为0)。并设置序列长度为1(len=1;
),然后再看从数字1开始的这个序列最长能到哪里,用for(;a[k]<a[k+1];k++)
中的a[k]<a[k+1]
来判断。
若后面的数字大于当前数字,则满足递增,同时len++;
序列长度加一。例如:1<9 , len:1->2。9>2,不满足递增,则以第一个数字1为首的最大序列找到。
将全局变量mpos和mlen,分别赋值为pos和len,表示当前最长的序列的下标和长度。
之后从第2个数字开始,继续循环。每次要和全局变量mpos和mlen比较,修改mpos和mlen。
最后得到的是最后出现的最长的序列,但不一定是第一个,所以要在找一次,寻找递增数列len==mlen的。
因为做的事情和之前一样,所以就又在原来的函数中添加了一个判断。
if(flag&&len==mlen2)
{
mpos=pos;
}
用了mlen2来保存最大长度。还用了一个标志变量flag,以确保第一次调用的时候不会执行这部分。
我的代码(20分的放心用,虽然这代码可能不咋地)
#include <stdio.h>
#define N 100000
int mlen;
int mlen2;
int flag=0;
int mpos;
void find(int *a,int n);
int main ()
{
int i,n;
int * a;
scanf("%d",&n);
a=(int *)malloc(sizeof(int)*n);
for(i=0;i<n;i++)
{
scanf("%d",a+i);
}
find(a,n);
//printf("%d %d\n",mpos,mlen); 测试用的
mlen2=mlen;
find(a,n);
for(i=mpos;i<mpos+mlen2-1;i++)
{
printf("%d ",a[i]);
}
printf("%d",a[i]);
return 0;
}
void find(int *a,int n)
{
int i,k,sum,pos,max=0,len;
for(i=0;i<n-1;i++)
{
k=i;
pos=k;
len=1;
for(;a[k]<a[k+1];k++)
{
len++;
}
if(flag&&len==mlen2)
{
mpos=pos;
}
if(mlen<len)
{
mlen=len;
mpos=pos;
}
}
}
要是看不懂我写的,就别看了,我也隐隐觉得这想法和代码都有点渣。我再去看看别人的想法,实践后再来更新。
——————————更新 ———————————
下面的这段代码和我的想法一样,不过他是在函数中直接找到了并能输出第一个出现的。(他是靠同时记录了序列的起始位置完成的,我的没有记录结尾下标,就只能再调用一次了。)
来源https://blog.csdn.net/qq_36913610/article/details/82319910
#include <stdio.h>
#define MAXSIZE 100000
typedef struct Node{
int Data[MAXSIZE];
int size;
}Node, *List; /*传递结构指针效率高*/
List Read(List L);
void PrintSeq(List L);
int main(void){
Node node;
List L = &node;
L = Read(L);
PrintSeq(L);
return 0;
}
List Read(List L){
int n, i;
scanf("%d", &n);
L->size = n;
for(i=0; i<n; i++){
scanf("%d", &L->Data[i]);
}
return L;
}
void PrintSeq(List L){
int maxL, maxR, maxLen, l, r, len;
int i;
if(L->size==0)
return;
else{
maxL=maxR=0;
maxLen = 1;
}
l=r=0;
len = 1;
for(i=1; i<L->size; i++){
if(L->Data[i]>L->Data[i-1]){
r++;
len++;
}
else{ /*遇到非增长点更新*/
if(len>maxLen){
maxL = l;
maxR = r;
maxLen = len;
}
l=r=i;
len = 1;
}
}
if(len>maxLen){ /*遍历结束后再次判断以防遗漏*/
maxL = l;
maxR = r;
maxLen = len;
}
for(i=maxL; i<=maxR; i++){
if(i==maxL)
printf("%d", L->Data[i]);
else
printf(" %d", L->Data[i]);
}
}