给定一个顺序存储的线性表,请设计一个算法查找该线性表中最长的连续递增子序列。例如,(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
参考代码:
#include<stdio.h>
struct LNode{
int *Data;
int Last;
};
typedef struct LNode *List;
List MakeEmpty(int n);
void Find(List p);
int main()
{
int n;
scanf("%d",&n);
List p=MakeEmpty(n);
int i;
for(i=0;i<n;i++)
{
scanf("%d",&p->Data[i]);
}
p->Last=n-1;
Find(p);
}
List MakeEmpty(int n) //初始化顺序表
{
List p=(List)malloc(sizeof(struct LNode));
p->Data=(int *)malloc(n*sizeof(int));
p->Last=-1;;
return p;
}
void Find(List p) //查找最长连续递增子序列
{
if(p->Last==0) //当顺序表中只有一个元素时
{
printf("%d",p->Data[0]);
}
else
{
int count=1; //count为当前元素峰值
int ans=1; //ans为最大峰值
int m1=0,n1=0,m2=0,n2=0; //m1,n1为最长递增子序列数组下标范围
//m2,n2为当前递增子序列数组下标范围
for(int i=0;i<p->Last;i++)
{
if(p->Data[i+1]>p->Data[i])
{
count++;
n2=i+1;
}
else
{
count=1;
m2=i+1;
}
if(count>ans)
{
ans=count;
m1=m2;
n1=n2;
}
}
for(int i=m1;i<=n1;i++) //输出最长连续递增子序列
{
printf("%d",p->Data[i]);
if(i==n1)
{
printf("\n");
}
else
{
printf(" ");
}
}
}
}
思路:
这里我有参考LeetCode中一个作者的思路,这里我总结下自己的思路:
- 遍历顺序表
- count 为当前元素峰值, ans为最大峰值, m1,n1为最长递增子序列数组下标范围, m2,n2为当前递增子序列数组下标范围
- 初始化 count = 1,ans=1,m1=0,n1=0,m2=0,n2=0
- 从 0 位置开始遍历,遍历时根据前后元素状态判断是否递增,递增则 count++,n2=i+1,递减则 count=1,m2=i+1
- 如果 count>ans,则更新 ans和m1,n1
- 直到循环结束