题目:
最长连续递增子序列
给定一个顺序存储的线性表,请设计一个算法查找该线性表中最长的连续递增子序列。例如,(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
思考:可以用队列思想在单链表上设置队首队尾的整形变量来比较递增子序列长度,这也是我查阅到的比较简单的方法。代码在链接里
https://blog.csdn.net/qq_36913610/article/details/82319910
我想的是如果用真实队列应该怎么做呢?
直接队列方法如下:
建立队列结构体数组,包含两个队列,q0q1,设置flag利于q0q1的转换
• 步骤
• 1.令flag=0
• 2.遍历单链表,利用flag标识将数据先写入q[flag],当写入数据与之前数据不符合递增时,判断队列q0长度和q1长度,将短的队列清空,如若长度相同则清空当前队列从而保留第一连续递增子序列。并且将falg置为清空的队列下标。
3.重复2的步骤直至单链表遍历写入完成。
• 这就是遍历循环的循环体,最后再次判断两个队列的长度,长的一个就是最长连续递增子序列的队列(若相同则选择之前的队列),再遍历这个队列进行相应的输出。
代码如下
#include <stdio.h>
#define MAXSIZE 100000
typedef struct Node
{
int data[MAXSIZE];
int size;
}Node, *list;
typedef struct queue
{
int data[MAXSIZE];
int front;
int rear;
};
list Read(list L, int n);
void output(list l, int n);
list Read(list L, int n)
{
int i;
L->size = n;
for (i = 0; i<n; i++)
{
scanf("%d", &L->data[i]);
}
return L;
}
void output(list l, int n)
{
struct queue q[2];
q[0].front = 0;
q[0].rear = 0;
q[1].front = 0;
q[1].rear = 0;
q[0].data[0] = l->data[0];
q[0].rear += 1;
int flag = 0;
for (int i = 1; i < n; i++)
{
if (l->data[i] > q[flag].data[q[flag].rear - 1])
{
q[flag].data[q[flag].rear] = l->data[i];
q[flag].rear += 1;
}
else
{
if (flag == 0)
{
if (q[0].rear - q[0].front > q[1].rear - q[1].front)
{
flag++;
q[1].front = q[1].rear;
q[flag].data[q[flag].rear] = l->data[i];
q[flag].rear++;
}
else
{
q[0].front = q[0].rear;
q[flag].data[q[flag].rear] = l->data[i];
q[flag].rear++;
}
}
else
{
if (q[1].rear - q[1].front > q[0].rear - q[0].front)
{
flag--;
q[0].front = q[0].rear;
q[flag].data[q[flag].rear] = l->data[i];
q[flag].rear++;
}
else
{
q[1].front = q[1].rear;
q[flag].data[q[flag].rear] = l->data[i];
q[flag].rear++;
}
}
}
}
if (q[0].rear - q[0].front > q[1].rear - q[1].front)
{
for (int x = 0; x<q[0].rear - q[0].front; x++)
{
if (x == q[0].rear - q[0].front - 1)
printf("%d", q[0].data[q[0].front + x]);
else
printf("%d ", q[0].data[q[0].front + x]);
}
}
if (q[0].rear - q[0].front < q[1].rear - q[1].front)
{
for (int x = 0; x<q[1].rear - q[1].front; x++)
{
if (x == q[1].rear - q[1].front - 1)
printf("%d", q[1].data[q[1].front + x]);
else printf("%d ", q[1].data[q[1].front + x]);
}
}
else
{
if (flag == 0)flag++;
else flag--;
for (int x = 0; x<q[flag].rear - q[flag].front; x++)
{
if (x == q[flag].rear - q[flag].front - 1)
printf("%d", q[flag].data[q[flag].front + x]);
else
printf("%d ", q[flag].data[q[flag].front + x]);
}
}
}
int main()
{
Node node;
list L = &node;
int n;
scanf("%d", &n);
L = Read(L, n);
output(L, n);
return 0;
}
当时脑子想复杂了,队列组可以改为最大串队列q1和中间队列q2,将最大序列存入q1,用q2来判断之后的序列长度是否比q1大,可简化循环中判断的操作。
#include <iostream>
#include <queue>
using namespace std;
class Solution {
public :
void add(int elem) {
if(elem <= tempQueue.back()){
if(tempQueue.size() > maxQueue.size())
maxQueue = tempQueue;
tempQueue = queue<int>();
}
tempQueue.push(elem);
}
void show() {
cout << maxQueue.front();
maxQueue.pop();
while(!maxQueue.empty()) {
cout << " " << maxQueue.front();
maxQueue.pop();
}
}
private:
queue<int> maxQueue;
queue<int> tempQueue;
};
int main() {
int N;
cin >> N;
Solution S;
for(int i = 0; i < N ;i ++) {
int temp;
cin >> temp;
S.add(temp);
}
S.show();
}