Research on the subsequence problem with the longest increment in array (2)

Source: Internet
Author: User

In the previous article, we learned how to get the length of the longest incrementing sub-sequence of a one-dimensional array, but we do not know what this sub-sequence is! How can we list such a longest incrementing subsequence that meets the requirements?

In the second method described earlier, we used a MINV array, which is helpful for the subsequent implementation. We traverse from the first element of an array until the value in the LIS array corresponding to this element is not greater than the length of the longest incrementing subsequence. Let's assume that we use current to indicate the current element of the final longest incrementing sub-sequence to be obtained. If current is equal to 1, we will look for the first element in the sub-sequence. Add current to 1 after each query to find the next element. We also need to make some judgments on elements with the same Lis value. The following is an algorithm:

public static int lis2(int[] array){if(array==null||array.length==0)return -1;int len=array.length;int[] lis=new int[len];int maxlength=1;int[] minV=new int[len+2];minV[0]=minArray(array)-1;minV[1]=array[0];Arrays.fill(lis, 1);for(int i=1;i<len;i++){int j;for(j=maxlength;j>=0;j--){if(array[i]>minV[j]){lis[i]=j+1;break;}}if(lis[i]>maxlength){maxlength=lis[i];minV[lis[i]]=array[i];}else if(minV[j]<array[i]&&array[i]<minV[j+1]){minV[j+1]=array[i];}}minV[maxlength+1]=Integer.MAX_VALUE;System.out.println(Arrays.toString(lis));int current=1;for(int i=0;i<lis.length&¤t<=maxlength;i++){if(lis[i]==current){if(array[i]>minV[current+1])continue;System.out.print(array[i]+" ");current++;}}System.out.println();return maxlength;}

The running result is as follows:

1 2 4 5 7 length: 5 time: 285272 nanoseconds

If you have a better method, please advise.

The above provides a method for finding the longest recursive subsequence. We know that for an array, there may be multiple longest incrementing subsequences (these longest incrementing subsequences must have the same length). How can we obtain all the longest incrementing subsequences and list them all? I have thought of a method to share it with you. If you have any good method, please share it!

My idea is to use recursive methods. We compile a function that can search for the number of levels in a subsequence starting from a subscript, such as outputlis (INT level, int index, int [] Lis, int [] array, int [] MINV), where level indicates the number of digits in the subsequence we are looking for, index indicates the subscript from which to start searching, array is the original array, lis stores the possible position of the corresponding element in the final ascending subsequence. minv [I] stores the minimum value of the maximum element of the longest ascending subsequence with the length of I. Of course, we also need to use another array information in this method. This array is used to indicate whether an element in the original array is selected in the longest incrementing subsequence. The specific algorithm is given below:

// Output all the longest recursive subsequences Private Static void outputlis (INT level, int index, int [] Lis, int [] array, int [] MINV) {If (Level = maxlength + 1) {for (INT I = 0; I <flag. length; I ++) {If (flag [I]) {system. out. print (array [I] + "") ;}} system. out. println (); return;} while (LIS [Index]! = Level & index <array. length) index ++; while (index <array. length & Lis [Index] <LEVEL + 1) {If (LIS [Index] = level & array [Index] <MINV [Lis [Index] + 1]) {flag [Index] = true; outputlis (LEVEL + 1, index + 1, Lis, array, MINV); flag [Index] = false ;}index ++ ;}}

The running result is as follows:

1 2 4 5 7-1 2 4 5 7 length: 5: 422708 nanoseconds

Next, I will attach the complete program for your reference. Lis1 only calculates the length of the longest incrementing subsequence. lis2 calculates the length and lists a longest incrementing subsequence. lis3 calculates the length and returns all the longest incrementing subsequences.

Package COM. application. sample; import Java. util. arrays; import Java. util. iterator; import Java. util. stack; // obtain the longest incremental sub-sequence of a sequence public class lissample {Private Static Boolean [] flag; Private Static int maxlength; public static void main (string [] ARGs) {// todo auto-generated method stubint [] arr = {1,-6, 7}; long start = system. nanotime (); system. out. println ("Length:" + lis1 (ARR); long end = system. nanotime (); System. out. println ("time used:" + (end-Start) + "nanosecond"); Start = system. nanotime (); system. out. println ("Length:" + lis2 (ARR); End = system. nanotime (); system. out. println ("time used:" + (end-Start) + "nanosecond"); Start = system. nanotime (); system. out. println ("Length:" + lis3 (ARR); End = system. nanotime (); system. out. println ("time:" + (end-Start) + "nano");} public static int lis1 (INT [] array) {If (array = NULL | array. length = 0) Return-1; int Len = array. length; int [] Lis = new int [Len]; for (INT I = 0; I <Len; I ++) {Lis [I] = 1; for (Int J = 0; j <I; j ++) {If (array [J] <array [I] & (LIS [J] + 1)> Lis [I]) {Lis [I] = Lis [J] + 1 ;}} system. out. println (arrays. tostring (LIS); Return maxarray (LIS);} public static int lis2 (INT [] array) {If (array = NULL | array. length = 0) Return-1; int Len = array. length; int [] Lis = new int [Len]; int maxlength = 1; int [] MINV = new int [Len + 2]; MINV [0] = minarray (array) -1; MINV [1] = array [0]; arrays. fill (LIS, 1); For (INT I = 1; I <Len; I ++) {Int J; For (j = maxlength; j> = 0; j --) {If (array [I]> MINV [J]) {Lis [I] = J + 1; break;} If (LIS [I]> maxlength) {maxlength = Lis [I]; MINV [Lis [I] = array [I];} else if (MINV [J] <array [I] & array [I] <MINV [J + 1]) {MINV [J + 1] = array [I] ;}} MINV [maxlength + 1] = integer. max_value; system. out. println (arrays. tostring (LIS); int current = 1; for (INT I = 0; I <Lis. length & lt; = maxlength; I ++) {If (LIS [I] = current) {If (array [I]> MINV [current + 1]) continue; system. out. print (array [I] + ""); current ++;} system. out. println (); Return maxlength;} public static int lis3 (INT [] array) {If (array = NULL | array. length = 0) Return-1; int Len = array. length; flag = new Boolean [Len]; int [] Lis = new int [Len]; int maxlength = 1; int [] MINV = new int [Len + 2]; MINV [0] = integer. min_value; MINV [1] = array [0]; arrays. fill (LIS, 1); // For (INT I = 1; I <Len; I ++) // {// in T j; // For (j = Lis [I-1]; j> 0; j --) // {// If (array [I]> MINV [J]) // {// Lis [I] = J + 1; // break; //} // If (LIS [I]> maxlength) /// {// maxlength = Lis [I]; // MINV [Lis [I] = array [I]; //} else if (MINV [J] <array [I] & array [I] <MINV [J + 1]) // {// MINV [J + 1] = array [I]; //} For (INT I = 1; I <Len; I ++) {Int J; For (j = maxlength; j> = 0; j --) {If (array [I]> MINV [J]) {Lis [I] = J + 1; break;} If (LIS [I]> maxlength) {maxlength = Lis [I]; MINV [Lis [I] = array [I];} else if (MINV [J] <Array [I] & array [I] <MINV [J + 1]) {MINV [J + 1] = array [I] ;}} system. out. println (arrays. tostring (LIS); MINV [maxlength + 1] = integer. max_value; system. out. println (arrays. tostring (MINV); lissample. maxlength = maxlength; outputlis (, Lis, array, MINV); Return maxlength;} // output all the longest recursive subsequences Private Static void outputlis (INT level, int index, int [] Lis, int [] array, int [] MINV) {If (Level = maxlength + 1) {for (INT I = 0; I <flag. length; I ++) {If (flag [I]) {system. out. print (array [I] + "") ;}} system. out. println (); return;} while (LIS [Index]! = Level & index <array. length) index ++; while (index <array. length & Lis [Index] <LEVEL + 1) {If (LIS [Index] = level & array [Index] <MINV [Lis [Index] + 1]) {flag [Index] = true; outputlis (LEVEL + 1, index + 1, Lis, array, MINV); flag [Index] = false ;}index ++ ;}} private Static int minarray (INT [] array) {int result = array [0]; for (INT I = 1; I <array. length; I ++) {If (array [I] <result) Result = array [I];} return result;} Private Static int maxarray (INT [] array) {int result = array [0]; for (INT I = 1; I <array. length; I ++) {If (array [I]> result) Result = array [I];} return result ;}}

The overall running result is as follows:

[1, 1, 2, 1, 3, 1, 4, 1, 5] duration: 5: 360476 nanoseconds [1, 1, 2, 1, 3, 1, 4, 1, 5] 1 2 4 5 7 length: 5: 433169 nanoseconds [1, 1, 2, 1, 3, 1, 4, 1, 1, 5] [-2147483648,-6, 2, 4, 5, 7, 2147483647, 0, 0, 0, 0] 1 2 4 5 7-1 2 4 5 7 length: 5: 451083 nanoseconds

Thank you for your comments and good methods! Indicate the source for reprinting.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.