算法导论15.4-6 求一个n个数的序列的最长单调递增子序列 O(n*logn)
2014-10-18 21:36
411 查看
算法导论 15.4-6
Give an O(nlgn) time algorithm to find the longest monotonically increasing subsequence of a sequence of n numbers.
(Hint: Observe that the last element of a candidate subsequence of length i is at least as large as the last element of a candidate subsequence of length i-1.
Maintain candidate subsequences by linking them through the input sequence.)
子序列下标不要求是连续的。参考两篇文章:
http://blog.csdn.net/wdq347/article/details/8978394 http://blog.csdn.net/wangche320/article/details/9185919
下面是Java代码。
算法导论 15.4-5 求一个n个数的序列的最长单调递增子序列 子序列下标不要求是连续的
Give an O(n^2) time algorithm to find the longest monotonically increasing
subsequence of a sequence of n numbers.
Give an O(nlgn) time algorithm to find the longest monotonically increasing subsequence of a sequence of n numbers.
(Hint: Observe that the last element of a candidate subsequence of length i is at least as large as the last element of a candidate subsequence of length i-1.
Maintain candidate subsequences by linking them through the input sequence.)
子序列下标不要求是连续的。参考两篇文章:
http://blog.csdn.net/wdq347/article/details/8978394 http://blog.csdn.net/wangche320/article/details/9185919
下面是Java代码。
/** * The max increasing subsequence must be ended with one(or several) of the array, * To find the max increasing subsequence, is to find all length subsequences ending with each array member, * and choose the max length in them. */ public static void findLongestIncreaseSubseq(int[] array, int n) { // O(nlgn) System.out.println(Arrays.toString(array)); int[] preValues = new int ; // the previous element of max subsequence for current element int[] minEnding = new int ; // the increasing min ending value of all max subsequence int minDefValue = -1; // or set to Integer.MIN_VALUE; for(int k=0; k<n; k++) { minEnding[k] = minDefValue; preValues[k] = minDefValue; } int maxLen = 1; // the length of max subsequence int maxIndex = 0; // the index of last element of max subsequence minEnding[0] = array[0]; for(int i=1; i<n; i++) { // 依次寻找以 array[i]结尾的递增子序列 //在所有子序列的最小结束元素数组中找到array[i]的插入位置 int pos = findPosByBinarySearch(minEnding, 0, maxLen, array[i]); if( pos == maxLen ){ minEnding[pos] = array[i]; maxLen ++; maxIndex = i; // set the former when find longer subsequence ending with current element preValues[i]=minEnding[pos-1]; } else { if(array[i] <= minEnding[pos]) { //if equal, the later still replace the former minEnding[pos] = array[i]; // current element is smaller then previous subsequence preValues[i] = minDefValue; } else { // if(array[i] > minEnding[pos]) // the former is minEnding[pos] for the subsequence ending with current element preValues[i] = minEnding[pos]; } } } // maxLen is the length of using minEnding System.out.println("max len:"+maxLen); System.out.println("minEndings:\n" + Arrays.toString(minEnding)); System.out.println("max index:"+maxIndex); System.out.println("preValues:\n" + Arrays.toString(preValues)); Queue<Integer> maxSeqQueue = new ArrayDeque<Integer>(); for(int index=0; index < preValues.length; index++) { if(preValues[index] != minDefValue) { maxSeqQueue.offer(preValues[index]); } } maxSeqQueue.offer(array[maxIndex]); System.out.println("max subsequence:\n"+maxSeqQueue); } /** * The minEnding is sorted array to store the min value of all length subsequences, * the index=0 means the increasing subsequence length is 1. */ static int findPosByBinarySearch(int[] minEnding, int start, int length, int value) { int end = length -1; if(value > minEnding[end]) { //若value大于最大子序列最小值,返回length return length; } if(value < minEnding[start]) { // 若value小于最小子序列最小值,返回0 return start; } // find the insert position for element by binary search O(lgn) while(start <= end) { int mid = (start+end) >>> 1; // 无符号右移 if(minEnding[mid] == value) { return mid; } else if(minEnding[mid] < value) { start = mid +1; } else if(minEnding[mid] > value) { end = mid -1; } } return start; // return the start position if not find equal one } public static void main(String[] args) { int[] array = { 4, 2, 3, 7, 6, 12, 5 }; findLongestIncreaseSubseq(array, array.length); int[] array1 ={0,1,3,5,1,4,6,7,0,8,9,2}; findLongestIncreaseSubseq(array1, array1.length); int[] array2 ={2,1,3,0,4,1,5,2,7}; findLongestIncreaseSubseq(array2, array2.length); }
算法导论 15.4-5 求一个n个数的序列的最长单调递增子序列 子序列下标不要求是连续的
Give an O(n^2) time algorithm to find the longest monotonically increasing
subsequence of a sequence of n numbers.
// find longest increase subsequence with dynamic programming public static void getLongestIncreaseSubseq(int[] array, int n) { // O(n^2) System.out.println(Arrays.toString(array)); int[] maxLengths = new int ; // the max length of current longest sequence int[] lastIndexs = new int ; // index of last element of longest sequence for(int k=0; k<n; k++) { maxLengths[k] = 1; // at least length is 1, and previous set to -1 lastIndexs[k] = -1; } int maxLen = 1; int maxIndex = 0; for (int i = 1; i < n; i++) { for (int j = 0; j < i; j++) { //循环比较当前元素和其之前所有元素 if (array[i] > array[j]) { //若比前面的元素大,是一个单增子序列中的元素 if (maxLengths[i] < maxLengths[j] + 1) { // 若当前子序列长度 < 前面元素的子序列长度+1 maxLengths[i] = maxLengths[j] + 1; lastIndexs[i] = j; // 若是子序列中的元素,记录比第i个数小的第j个数的下标 } } } if(maxLengths[i] > maxLen) { maxLen = maxLengths[i]; maxIndex = i; } } System.out.println("longest subsequence length:" + maxLen); System.out.println("longest subsequence last index:" + maxIndex); // System.out.println(Arrays.toString(maxLengths)); // System.out.println(Arrays.toString(lastIndexs)); System.out.println("longest subsequence:"); Deque<Integer> stack = new ArrayDeque<Integer>(); int k=maxIndex; for(; maxLengths[k] > 1; ) { stack.push(array[k]); k = lastIndexs[k]; } stack.push(array[k]); System.out.println(stack); }
相关文章推荐
- 算法导论 习题15.4-5 15.4-6 找出一个n个数的序列中最长的单调递增子序列
- 算法导论15.4-6:最长单调递增子序列
- 算法导论15.4-6 最长递增子序列(nlogn)
- 设计一个O(n2)时间的算法,找出由n个数组成的序列的最长单调递增子序列。
- 求最长不增子序列、最长单调递减子序列、最长不降子序列、最长单调递增子序列长度
- 最长单调递增子序列-LIS问题
- 最长单调递增子序列O(NlogN)算法
- 最长单调递增子序列( O(nlgn) )
- 单调递增子序列(二)(n*logn)
- 二分求最长单调递增子序列并输出最长的序列(模板)
- UVA10534:Wavio Sequence(最长递增和递减序列 n*logn)(LIS)好题
- nyoj17单调递增最长子序列(N*logN)
- hdu 1257 最少拦截系统(最长单调递增序列)
- 给定一个长度为N的数组,找出一个最长的单调自增子序列(不一定连续,但是顺序不能乱). 第二解
- 【动态规划】LIS最长单调递增子序列 logn算法 并且输出子序列
- 求一个序列中的最长严格递增子序列。
- 给定一个长度为N的数组,找出一个最长的单调自增子序列(不一定连续,但是顺序不能乱).
- 最长单调递增子序列(网络24题,六)
- 最长单调递增子序列(二分查找优化)
- 最长单调递增公共子序列(路径记录+poj2127+zoj2432)Greatest Common Increasing Subsequence