`
chriszeng87
  • 浏览: 741204 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

编程之美2.16 数组中最长递增子序列的长度 O(nlgn)

阅读更多

题目:

       设L=<a1,a2,…,an>是n个不同的实数的序列,L的递增子序列是这样一个子序列Lin=<aK1,ak2,…,akm>,其中k1<k2<…<km且aK1<ak2<…<akm。求最大的m值。

 

 

在下面的代码中

lis[i]表示以array[i]结尾的递增子序列的最大长度,

max[j]表示长度为j的递增子序列的最大元素的最小值,

则max[lis[i]]表示长度为lis[i]的递增子序列的最大元素的最小值,即array[i].

 

package beautyOfProgram;

public class LIS {

	int  INT_MIN = -1000000;

	public int binary_search(int[] a,int len,int n)//若返回值为x,则a[x]>=n>a[x-1]
	{
		int left=0,right=len-1,mid=(left+right)/2;
	    while(left<=right)
	    {
	        if(n>a[mid]) left=mid+1;
	        else if(n<a[mid]) right=mid-1;
	        else return mid;
	        mid=(left+right)/2;
	    }
	    return left;

	}

	public int lis(int[] arr, int len)
	{
		int[] max = new int[len+1];
		int[] lis = new int[len];

		max[0] = INT_MIN;
		max[1] = arr[0];
		int maxLis = 1;
		for(int i=0;i<len;i++)
		{
			
			//遍历
			/*for(int j=maxLis;j>=0;j--)
			{
				if(arr[i] > max[j])
				{
					lis[i] = j+1;
					break;
				}
			}*/

			//二分查找
			lis[i] = binary_search(max,maxLis+1,arr[i]);

			if(lis[i] > maxLis) //arr[i]大于前面所有的数
			{
				max[lis[i]] = arr[i];
				maxLis = lis[i];
			}
			else if(max[lis[i]-1] < arr[i] && arr[i] < max[lis[i]])
			{//arr[i]比当前最长的子序列的最后一个小,比它前面一个又大
				max[lis[i]] = arr[i];
			}
		}

		return maxLis;
	}
	
	public static void main(String[] args) 
	{
		int arr[] = {1,-1,2,-3,4,-5,6,-7};//{1,2,5,4,6};
		LIS l = new LIS();
		System.out.println(l.lis(arr,arr.length));
	}

}
0
1
分享到:
评论

相关推荐

    最长上升子序列nlgn源码

    输入序列,求最长上升子序列的长度,算法复杂度nlgn

    单调递增子序列

    最长单调递增子序列,运行时间为O(nlgn),为算法导论上的算法

    电路布线 (O(nlgn)的算法)

    最长上升子序列问题在计算机科学中是被广泛研究的,其求解算法也具有O(nlgn)的时间复杂度。在这里,作者可能利用LIS的思路来寻找电路元件之间的最优连接顺序,从而降低布线的交叉和复杂性。 总的来说,这三个PDF...

    最大连续子序列和

    这个解法的时间复杂度为 O(NlgN),因为我们需要对数组进行分治,并且对每一个子数组进行计算连续子序列和的操作。 解法 3:O(N)解法 这个解法是最优的解法,它只需要 O(N)的时间。思路是遍历数组中的每一个元素,...

    C++源程序测试数组中有多少个逆序对

    测试输入的数组中有多少个逆序对,本程序在归并排序的基础上实现,时间复杂度为O(nlgn)

    计算一个数组中逆序对的个数

    设A[1..n]是包含n个不同数的数组,如果i而且A[i]&gt;A[j],则(i,j)为一个逆序组,给出时间复杂度为nlgn算法,确定n个任意元素排列中逆序组的个数。

    3种方法求 最大连续子序列和

    解法1—O(N^2)解法 解法2—O(NlgN)解法 解法3—O(N)解法 可以直接在记事本运行

    An O(ND) Difference Algorithm

    Myers通过将LCS问题和SES问题映射到一个编辑图(Edit Graph)上,展示了一个简单且高效的O(ND)时间复杂度的算法,其中N表示两个序列的长度之和,D为最小编辑脚本的大小。这种视角使得算法能够在序列相似度较高时表现...

    2020_算法XD.pdf

    - 在动态规划用于解决最长公共子序列问题的递归关系中,c[i,j]代表x[1..i]和y[1..j]的最长公共子序列的长度。 通过这些知识点的解释,我们可以对算法领域中一些基本概念和经典问题有一个系统的认识。这些内容是...

    C语言快速排序.pdf

    在分解步骤中,序列被划分成两个可能为空的子序列,左边的子序列中的每个元素均小于或等于主元(也称为枢轴、支点),右边的子序列中的每个元素均大于主元。在解决步骤中,通过递归调用快速排序,对子序列进行排序。...

    归并排序最坏情况可运行jar

    归并排序并不像快速排序那样最坏情况时间复杂度变成On2,归并排序最坏情况仍然是Onlgn,大家可以看看

    java各种数组排序(插入,交换,选择,归类,基数排序).pdf

    - 归并排序:采用分治策略,将数组分成两个子数组分别排序,然后合并两个有序子数组。 - 基数排序:根据元素的每一位进行排序,从低位到高位,最终得到完全排序的结果。 2. **排序算法的选择** - 对于小规模数据...

    算法导论上机报告.docx

    然后,解决部分是递归求解排序子序列,合并部分是将已经排序的子序列进行合并得到所要的答案,时间复杂度为θ(lgn)。 在已经排好序的基础上,对其运用二分查找算法,时间复杂度为θ(lgn)。二分查找的条件为待查的...

    leetcode2sumc-Two-Sum-2-sorted-array:二和二排序数组

    leetcode 2 和 c 二和二排序数组 [LeetCode] Tw​​o Sum II - 输入数组已排序 给定一个已按升序排序的...文件2sumsorted.c使用二分法,时间复杂度为O(nlgn),文件2sumsortedversion2.c使用两个指针指向数组的头尾。

    中科大算法导论第一二次和第四次作业答案PPT课件.pptx

    1. 计算子数组 L 和 R 的长度。 2. 分别复制子数组到 L 和 R。 3. 初始化三个指针 i, j, k 分别对应 L, R, A。 4. 比较 L[i] 和 R[j],将较小的元素放入 A[k] 并更新对应指针。 5. 当某一个子数组为空时,将另一个子...

    算法分析与设计常见算法思想.pdf

    它的基本思想是先使每个子序列有序,然后使子序列段间有序。 3. 快速排序:是一种交换类排序,时间复杂度为O(nlgn)。它的基本思想是将要排序的数据分割成独立的两部分,然后再按此方法对这两部分数据分别进行快速...

    概率与计算课程作业 随机化快速排序和确定型快速排序的比较

    图分析:两个图中的确定型快排每次运行时间的长度有波动,这是因为运行程序的优先级比较低,容易被中断导致运行时间不一样,但是总体来说是平稳的。 从图一中我们可以看到,任意一组整型数组分别采用三种算法在运行...

    算法导论答案

    在合并函数中,创建了两个辅助数组L和R,分别存储两个子序列的元素。通过比较L和R中的元素,并将较小的元素依次放入数组A中,完成合并过程。最后,释放了辅助数组L和R所占用的内存空间。 2. 算法的时间复杂度分析:...

    1987年对比算法论文

    Myers通过将问题映射到编辑图中的最短路径问题上,发展出了一种时间复杂度和空间复杂度均为O(ND)的高效算法,其中N是两个序列长度之和,而D是最小编辑脚本的大小。这种算法在处理相似性较高的序列时尤其高效,因此在...

    线性时间排序.pptx

    1. 初始化计数数组C,长度为数据的最大值k。 2. 遍历输入数组A,统计每个元素出现的次数,并存储到C中。 3. 计算前缀和,使得C[i]表示小于或等于i的元素的总数。 4. 从后向前遍历A,将元素按照累计计数值B[C[A[j]]]...

Global site tag (gtag.js) - Google Analytics