`
java-mans
  • 浏览: 11454258 次
文章分类
社区版块
存档分类
最新评论

【100题】 第四十七题 序列的最长递增、递减序列

阅读更多

一,题目

求一个数组的最长递减子序列

比如{94325432}的最长递减子序列为{95432}

求一个数组的最长递增子序列

比如{1,-1,2,-3,4,-5,6,-7}的最长递减子序列为{12436}


二,递增序列长度求解方法

解法一:

时间复杂度为 o(n^2)

遍历数组序列,每遍历一个数组元素,则求序列到当前位置 最长的递增序列数,用temp[i]存储。

注意,当前的最长递增子序列受已经遍历的最长递增子序列影响,从序列头 再遍历到当前位置的前一个位置,挨个比较 a[j]与a[i](当前元素)大小,遇到小于a[i]且判断需要更新

temp[]数组。

     由于这里仅仅是求,最长递增序列的长度,所以仅仅用temp[]存储长度大小。

                                                                                                                                                                       源码:

#include <iostream>
using namespace std;

int LIS(int array[],int n)
{
	int temp[n];//存放当前遍历位置最长序列 
	for(int i=0;i<n;++i)
	{
		temp[i]=1;   //初始化 默认长度 
		for(int j=0;j<i;++j) //找出前面最长的序列 
		{
			// 当前值 array[i] 跟已经遍历的值比较,
		    //大于已经遍历的值且已知递增序列+1 大于当前值则 更新当前最长递增序列值 
			if(array[i]>array[j]  && temp[j]+1 > temp[i] )
			{
				temp[i] = temp[j] + 1;
			}
			
		}
	}
	
	int max=temp[0];
	for(int k=0;k<n;++k)//找出整个数组中最长的子序列 
	{
		if(max<temp[k])
			max=temp[k];
	}
	
	return max;
	
}

int main()
{
	int arr[]={1,-1,2,-3,4,-5,6,-7};
	int result=LIS(arr,8);
	cout<<result<<endl;
	
}

解法二:时间复杂度任然为 O(n^2)

      为了减少比较次数

      采用空间换时间的策略。新增一个数组MaxV[],max[i]表示所有长度为i的递增子序列中最大值之间的最小值

      nMaxlax记录当前最长子序列

      每次遍历一个元素时候,从最长子序列开始遍历,一直到1 比较当前元素值arr[i] 跟MaxV[j]的值,从而更新temp[]最长子序列和nMaxLax和MaxV[]的值

  源码:

#include <iostream>
using namespace std;

int LIS(int array[],int n)
{
	int temp[n];//存放当前遍历位置最长序列 
	int  MaxV[n]; //最长子序列中最大值之间的最小值
	MaxV[1]=array[0];//初始序列长度为1的子序列 中最大值的最小值
    MaxV[0]=-9999;//边界值
	 
	 for(int i=0;i<n;++i)
	{
		temp[i]=1;   //初始化 默认长度 
	} 
	 int  nMaxLis=1;
	 int  j; 
	for(int i=0;i<n;++i)
	{
		for(j=nMaxLis;j>=0;--j) //找出前面最长的序列 
		{
			if(array[i]>MaxV[j])//当前值大于长度为j的子序列中最大值之间的最小值 
			{
				temp[i] = j + 1;
				break; 
			}
			
		}
		
		if(temp[i]>nMaxLis)//在最长子序列时停止 (这时只有一个最长的) 
		{
			cout<<"nMaxLIs"<<nMaxLis<<endl; 
			
			nMaxLis=temp[i];
			MaxV[temp[i]]=array[i]; 
		} 
		else if(MaxV[j] <array[i] && array[i]<MaxV[j+1])
		{
			MaxV[j+1]=array[i]; 
		} 
	}
	
	
	return nMaxLis;
	
}

int main()
{
	int arr[]={1,-1,2,-3,4,-5,6,-7};
	int result=LIS(arr,8);
	cout<<result<<endl;
	
}

  解法三:

      将内循环查询部分换成二分搜索,则时间复杂度降低为 O(nlogN)


三,递减序列 最长子序列求解方法

用index数组,从大到小排序。然后依次遍历元素,查找元素在index数组中的位置pos ,根据位置来判断当前最长的子序列。

#include<iostream>
#include<cassert>
#include<stack>
using namespace std ;
int BiSearch(int *A,int nTarget,int nLen);

void FindLongestSequence(int *A,int nLen)
{
	int *index=new int[nLen];//存放子序列 
	int *LDS=new int[nLen];
	
	index[0]=A[0];
	LDS[0]=1;
	int indexLen=1; //最长递增子序列 长度 
	
	for (int i=1;i<nLen;i++)
	{
		//这里是关键,在已经加入的 序列中查找当前序列的插入位置
		 
		int pos=BiSearch(index,A[i],indexLen);
		
		index[pos]=A[i];
		LDS[i]=pos+1;//记录当前最长序列
		 
		if(pos>=indexLen)//插入的当前位置大于最长序列 
			indexLen++;
	}
	
	int ResultLen=indexLen;
	for (int i=nLen;i>=0;i--)//记录最长递减子序列 
	{
		if(LDS[i]==ResultLen)
		{	
			index[ResultLen-1]=A[i];
			ResultLen--;
		}		
	}

	for (int i=0;i<indexLen;i++)
	{
		cout<<index[i]<<" ";
	}
	delete []index;

}
int BiSearch(int *A,int nTarget,int nLen)//二分搜索 
{
	assert(A!=NULL&&nLen>0);
	int start=0;
	int end=nLen-1;
	while (start<=end)
	{
		int mid=(start+end)/2;
		if(nTarget>A[mid])
			end=mid-1;
		else if(nTarget<A[mid])
			start=mid+1;
		else
			return mid;
	}
	return start;
}
int main()
{
	int A[]={9,4,3,2,5,4,3,2,77,76};
	int nLen=sizeof(A)/sizeof(int);
	FindLongestSequence(A,nLen);
	return 1;
}



分享到:
评论

相关推荐

    动态规划算法中对子序列的一些模板

    里面主要有关于线性问题中最长公共子序列,最长递增递减子序列,最大子段和,需不需要输出位置,还有最长公共递增子序列,当然,最重要的是可以直接用

    将两个递增的链表合并为一个非递减的链表

    从键盘输入两个链表,通过程序对他们排序,之后按递增顺序合并链表

    陈越、何钦铭-数据结构作业2:顺序链表合并

    本题要求实现一个函数,将两个链表表示的递增整数序列合并为一个非递减的整数序列。L1和L2是给定的带头结点的单链表,其结点存储的数据是递增有序的;函数Merge要将L1和L2合并为一个非递减的整数序列。应直接使用原...

    二分 查找 给定一个单调递增的整数序列,问某个整数是否在序列中

    给定一个单调递增的整数序列,问某个整数是否在序列中

    排序(数据结构最后一次作业)

    大连理工大学软件学院11级 数据结构最后一次上机作业 包括3中插入排序 2中交换排序 简单选择排序和 归并排序 课后6、7题 将一组数中所有负数元素放在非负数元素之前;同时找出一组数据中的最大值和最小值

    数据结构第5次作业.docx

    1. 算法设计题 :已知n元顺序表a0, a1, … , an-1按关键字递增有序存储。给定关键字值key,编写算法用对分查找求下标i,满足ai-1且aikey。 2. 编程题:输入n个两两互不相等的整数,以这些整数为关键字建立平衡的二叉...

    线性调频-区分是递增还是递减:递增或递减的线性调频信号在傅立叶域中给出相同的频谱。-matlab开发

    增加和减少线性调频信号在傅立叶域中给出相同的频谱。 那么如何找出它是什么?...它的'信号的相位。 相位正好相反。 请参阅生成的 matlab 图以了解您。 该文件适用于想要了解 FFT 和相位在 chirp 中的作用的初学者。

    subseq:子序列功能

    子序列 返回int子序列的函数。 最长的递增子序列 最长的递减子序列 最长的公共子序列 公共区域。

    对一个含有N整数的数组,使用堆排序让其由小到大输出

    堆排序 对一个含有N整数的数组,使用堆排序让其由小到大输出 样例输入 6 43 2 56 1 22 9 样例输出 1 2 9 22 43 56 堆排序 对一个含有N整数的数组,使用堆排序让其由小到大输出 样例输入 6 43 2 56 1 22 9 样例...

    Python数据结构(一):列表、元组和序列

    1.序列类型及操作 序列是具有先后关系的一组元素。序列是一个基类类型,具体可以表现为字符串类型、元组类型、列表类型。 序列是一维元素向量,元素类型可以不同。 它类似于数学当中的元素序列(数列):s1,s2,…...

    用链表实现有序合并集运算

    编程实现将两个有序表合并后仍然有序功能,要求分别采用数组法与链表法,并分析两种方法各自的优缺点。若用表La、Lb分别代表两个已存在的有序表,Lc为算法完成后产生新的有序表。可行的算法之一为:从表La与Lb中各取...

    rust-counter:Rust中的简单计数器。 递增,递减和重置。 查看分支以获取更多使用信息

    contract/src/lib.rs提供了递增/递减计数器并获取其当前值或重置的方法。 加号和减号按钮相应地增加和减少值。 切换按钮L时,只是为了好玩而打开了一点灯。 RS按钮用于重置。 LE和RE按钮让机器人对你眨眨眼。 跑步...

    PLSQL序列

    PLSQ语句 1.序列 create sequence seq_XXX start with 1 increment by 1 maxvalue 99999999 nocycle; 解释:1)INCREMENT BY用于定义序列的步长,如果省略,则默认为1,如果出现负值,则...对于递减序列,最大值是-1。

    数据结构回文判断.doc

    定义两个指 针,一个指向队头,一个指向队尾,队头的指针不断递增,队尾的指针不断递减,在P1 的前提下,两个地址上的数据进行比较,如相等则两地址分别向中间靠拢,如对比的 结果不同则跳出,但此时P1指针小于P2...

    一种基于序列数的关联规则挖掘算法① (2011年)

    为了在计算支持数时减少扫描事务数据库的次数,提出了一种基于序列数的关联规则挖掘算法,其关联规则适合挖掘任何长度该算法用事务属性的布尔约简法,将传统事务数据转换成二进制数,然后用数字的递增和递减两种方式...

    dowalle#algo#376-[一次遍历]-摆动序列1

    376. 摆动序列方法:模拟时间复杂度:O(n)空间复杂度:O(1)// 初始化第一个flag// 剩下的情况是,递增、递减、保持不变,就直接跳过。

    MAT2FIGURE - 用于轻松浏览时间序列数据的 GUI:将时间序列数据转换为图形文件以查看和分发数据-matlab开发

    - 在信号选择器处,每个信号都被标记,无论是普通信号,只是具有恒定值还是单调递增/递减- 信号可以绘制到现有的或新的子图中,时间轴是链接的,子图最多可以重新排列为 6 列- 可以创建当前图的快照,以便在不同...

    分数布朗运动时间序列的基于递归图的网络分析* (2012年)

    我们发现,对固定的Hurst指数日,在网络连通率首次增长到1之前,随着递归图的参数阈值的增大,网络的平均路径长度L也随之递增,之后反而递减.我们也发现由FBM时间序列转化得到的网络是无标度网络.我们采用节点覆盖...

    ORACLE错误码及解决方法

    ORA-04014 CYCLE类型的递减序列必须指定MINVALUE参数 定义一个递减序列,并且定义该序列的类型为CYCLE类型。需要添加MINVALUE参数来指定该序列何时进行循环。 ORA-04015 CYCLE类型的递增序列必须指定MAXVALUE参数 ...

    python实现合并两个排序的链表

    输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。 吐槽 本来想用递归实现,但是大脑卡壳,没有想到合适的递归策略,潜意识里还是把两个链表当成两个数组来看待,写出...

Global site tag (gtag.js) - Google Analytics