2021-09-19

查找线性表中最长递增子序列

给定一个顺序存储的线性表,请设计一个算法查找该线性表中最长递增子序列。例如,(1,9,2,5,7,3,4,6,8,0)中最长的递增子序列为(3,4,6,8)。

输入样例:
10
1 9 2 5 7 3 4 6 8 0
输出样例:
3 4 6 8

#include <stdio.h>
#include <malloc.h>
struct ming {
	int data[1000];
	int last;
};
struct ming* M;
struct ming* kongbiao(int a[], int n);
void zuichang(int i, int n);
int main()
{
	int a[1000], b[1000];
	int i = 0, n;
	scanf_s("%d", &n);
	M = (struct ming*)malloc(sizeof(struct ming));
	M = kongbiao(a, n);
	zuichang(i, n);
	return 0;
}
struct ming* kongbiao(int a[], int n)  //建立新表并赋值
{
	struct ming* M;
	int i = 0;
	M = (struct ming*)malloc(sizeof(struct ming));
	for (i = 0;i < n;i++)
	{
		scanf_s("%d", &a[i]);
		M->data[i] = a[i];
	}
	M->last = n;
	return M;
}
void zuichang(int i, int n)  //查找最长递增子序列
{
	int chazhi = 0, cishu = 0;
	int k = 0;
	int maxchang = 0, thischang = 1;   //注意当前长度从自身,即1开始
	for (i = 0;i < n;i++)
	{
		chazhi = M->data[i + 1] - M->data[i];  //后面减前面的差值大于0表示递增
		if (chazhi > 0)
		{
			thischang++;  //当前递增子序列长度
			if (thischang > maxchang)
			{
				maxchang = thischang;  //更换最大子序列长度
				k = i + 1;   //最新下标,位置记号
				cishu++;  //递增次数累加
			}
		}
		else if (chazhi < 0)
		{
			thischang = 1;   //重置当前序列长度
		}
	}
	for (i = k - cishu;i <= k;i++)   //k-cishu表示最长递增序列的头
	{
		printf("%d ", M->data[i]);  
	}
}

下面是我运行的结果
在这里插入图片描述

### 回答1: 算法步骤如下: 1. 初始化变量max_len为1,表示当前最长连续递增序列的长度为1。 2. 初始化变量cur_len为1,表示当前正在查找的连续递增序列的长度为1。 3. 从线性表的第二个元素开始遍历,依次比较当前元素和前一个元素的大小关系。 4. 如果当前元素大于前一个元素,则将cur_len加1,表示当前正在查找的连续递增序列长度增加了1。 5. 如果当前元素小于等于前一个元素,则将cur_len重置为1,表示当前正在查找的连续递增序列被断了。 6. 每次更新cur_len后,都将其与max_len比较,如果cur_len大于max_len,则更新max_len为cur_len。 7. 遍历完整个线性表后,max_len即为该线性表最长的连续递增序列的长度。 8. 如果需要找到具体的最长连续递增序列,可以记录下最长序列的起始位置和结束位置,然后将这段序列输出即可。 算法的时间复杂度为O(n),空间复杂度为O(1)。 ### 回答2: 算法设计思路: 1. 定义count记录当前递增数列长度,定义maxCount记录最大递增数列长度,定义startIndex记录当前递增数列的起始下标,定义maxStartIndex记录最大递增数列的起始下标。 2. 从第二个元素开始扫描整个线性表,若当前元素比前一个元素大,则递增数列长度count加1;否则,更新maxCount和maxStartIndex以及重置count和startIndex。 3. 扫描结束后,返回maxStartIndex和maxCount即可。 该算法的时间复杂度为O(n),空间复杂度为O(1)。 算法实现代码如下: int findLongestIncreasingSubSeq(int A[], int n) { int maxCount = 1, count = 1, startIndex = 0, maxStartIndex = 0; for (int i = 1; i < n; i++) { if (A[i] > A[i-1]) { count++; } else { if (count > maxCount) { maxCount = count; maxStartIndex = startIndex; } count = 1; startIndex = i; } } if (count > maxCount) { maxCount = count; maxStartIndex = startIndex; } return maxStartIndex; } ### 回答3: 线性表是一种基本的数据结构,它可以用顺序存储或者链式存储表示。在顺序存储线性表,元素按照一定的顺序依次排列。现在需要设计一个算法查找顺序存储线性表最长的连续递增序列。 具体的算法如下: 1. 定义两个变量,分别表示当前正在处理的序列的起点和终点。初始时,起点和终点都在表头,即起点为0,终点为1。 2. 定义一个变量,表示当前连续递增序列的长度。初始时,长度为1。 3. 遍历整个线性表,依次考虑每个元素。 4. 如果当前元素比前一个元素大,则说明当前元素可以加入到当前正在处理的递增序列,因此将终点向后移动一位,将长度加1。 5. 如果当前元素不比前一个元素大,则说明当前元素不能加入到当前正在处理的递增序列,因此需要重新开始一个新的递增序列。此时,将起点和终点均移动到当前元素所在位置,将长度设为1。 6. 在遍历过程,记录下最长的连续递增序列的长度以及起点和终点的位置。 7. 遍历结束后,即可得到最长的连续递增序列的长度以及起点和终点的位置。 8. 最后,根据起点和终点的位置,即可将最长的连续递增序列输出。 总之,以上算法通过遍历整个顺序存储线性表,依次处理每个元素,采用起点、终点和长度来记录递增序列的信息,最终输出最长的连续递增序列。这个算法的时间复杂度是O(n),其n是线性表的长度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值