#include <stdio.h>
int main()
{
int i,N;
scanf("%d",&N);
int Data[N];
for(i=0;i<N;i++)
scanf("%d",&Data[i]);
int Max=1, front=0,rear=0;//保留最终的结果
int head=0,tail=0,temp_max=0,last=0;//临时存放结果
//这里要注意每次更新i的值是怎样的
for(i=0;i<N;i=tail)
{
//初始化临时存放的最大值
//temp_max=1;
temp_max = 0;
//如果位置真不是没有抵达数组的最后
while(tail<N)
{
//tail = last +1;
//判断后一个值是否大于前一个值,
//if(Data[tail]>Data[last] && tail < N)
if(Data[tail]>Data[last])
{
//如果是,就满足递增序列要求,更新临时最大值,last与tail都后移一位
temp_max++;
last = tail;
tail++;
}
else
{//否则就不满足递增条件,跳出循环,同时将last向前移一位(因为跳出的时候last指向的是大的那个数字,如果不后移,会陷入死循环,tail得不到更新。
last++;
break;
}
}
//退出while循环意味着找完了一个递增序列,这时比较这个递增序列是否为当前的最长序列,如果是就更新最长序列的信息
if(temp_max>Max)
{
front = head;
rear = tail--;
Max = temp_max;
}
//将头指针初始化和尾指针指向同一位置,开启下一个循环。
head = tail;
}
printf("%d",Data[front]);
int t = front+1;
for(t;t<front+Max;t++)
printf(" %d",Data[t]);
return 0;
}
**这个程序还可以进一步优化,last和rear的值如何更新需要在深入思考,同时如果使用链表存放数据对于头尾的更新更容易理解一点(个人推测)
**
本题要求是输出最长连续递增子列,思考思路:第一反应是和输出最大和相似因此可以考虑在线处理,这样的话时间复杂度就是线性的,只需要扫描一遍就可以得到最终结果,如果对于长度相同的结果则只保留第一个子列
那按照这个思路,按照题目要求最终要输出最长子列,那就要求我们需要直到最长子列的信息,需要哪些信息才能输出呢?
首先对于输入用什么方式存放才合理呢?这里个人认为链表与数组均可,只是保存最长子列的方法有所差异,思想是相同的,同时链表会消耗更多的内存,所以这里使用数组实现。
思路1:用一个数组存放最长子列,优点:好想,第一反应就是这样,缺点。更新比较麻烦很难在线更新,同时空间开销比较大,
思路2:通过记录最长子列的起点与终点,优点:只需要两个整形的空间就可以输出最长子列,同时不用额外开辟空间。节省内存;
思路3:通过记录头结点与最大值同样可以实现
回到题目:
首先看一下递增序列有什么特点:
设一个队列:a1,a2……an
如果从ai->aj都是递增的,到aj+1就失去了递增的特点,那么可以推出 ak(k属于i到j任意数字)到aj与aj+1组成的序列都不是递增序列,exp:
在遍历完一个递增序列后,将这个递增序列的最大值temp_max
与当前序列最大值Max
比较,如果比当前的最大值大就更新最大值,然后从当前序列最后继续进行遍历。