最大子数组与最大子序列问题

先来看一个问题:给出一个数组,求这个数组的最大子序列。

这个问题很基础很常见,我们最简单的方法就是先准备一个数组

例如:arr[7]={1,2,5,8,4,3,2};

我们要求它的最长子序列,只要准备一个长度为7的数组和h[7]={0};

然后依次遍历arr将以arr中元素结尾的最长子序列放在h[7]中即可得到最长子序列的值,易得这是时间复杂度为O(n2);

再来看另一种做法,同样先准备一个数组h然后h中所存的元素先存arr[0],然后遍历,在和h中找到第一个比该元素大的,然后替换,若没有,则按顺序存入到h中,这样可以用二分查找,h中元素的意义为,当以该元素结尾的最长子序列为i+1;此时时间复杂度为

O(nlog(n));

这种算法是一个很复杂算法题的基础,就是当给定一系列二元组,(a1,b1),(a2,b2),(a3,b3),(a4,b4)...然后把这些二元组摞起来,

最多能摞多高,要求,ab都得从小到大,在其他地方,可能会看到俄国沙皇,一个代表权力,一个代表财富,思考一下这个问题因该怎么解决,很多地方来找到解法为O(n2)的算法,我们来看这一种解法。

********************

解法:

扫描二维码关注公众号,回复: 3007623 查看本文章

先把a排序,当a相等时,把b从大到小排列,然后就可以用最大子序列问题的方法来解决了,至于为什么要从大到小,因为要考虑a和b的权重,如果b很大,那么一定可以摞上去,所以要从大到小,这样就可以使用二分,所以时间复杂度就是O(nlong).

来一个两个数组最大子数组的问题,其本质思想就是第一个,我这里给出时间复杂度为O(n2)的,另一种,大家可以自己实现。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
char* lcs(char* s1,char* s2)
{
	int len1=strlen(s1);
	int len2=strlen(s2);
	int start,end,len;
	end=len=0;
	char c[len2];
	for(int i=0;i<len1;i++)
	{
		for(int j=len2-1;j>=0;j--)
		{
			if(s1[i]==s2[j])
			{
				if(i==0||j==0)
				{
					c[j]=1;
				}
				else
				{
					c[j]=c[j-1]+1;
				}
			}
			else
				c[j]=0;
			if(c[j]>len)
			{
				len=c[j];
				end=j;
			}
		}
	}
	start=end-len+1;
	char* p=malloc(len+1);
	for(int i=start;i<=end;i++)
	{
		p[i-start]=s2[i];
	}
	p[len]='\0';
	return p;
}
void main()
{
	char str1[255],str2[255];
	printf("input:\n");
	gets(str1);
	printf("input:\n");
	gets(str2);
	printf("%s\n",lcs(str1,str2));
}

用一个数组存放以str2中字符值结尾的最长子数组个数,然后遍历更新,最后输出位置和长度即可返回子数组。

猜你喜欢

转载自blog.csdn.net/Dachao0707/article/details/82049277