Solution to the longest incrementing subsequence problem (LIS)

Source: Internet
Author: User

This article introduces several algorithms with different complexity and provides implementation.

 

1. convert to the longest common subsequence (LCS) for solving

II. General DP

Iii. Lis O (nlogn) Algorithm

 

Problem description:

Set L = <A1, A2 ,..., An> is a sequence of n different real numbers. The ascending subsequence of L is such a subsequence lin = <ak1, ak2 ,..., AKM>, where k1 <k2 <... <Km and ak1 <ak2 <... <AKM. Evaluate the maximum m value.

It is obvious that there are differences between subsequences and substrings.

 

1. convert to the longest common subsequence (LCS) for solving, O (n2)

Set sequence X = <b1, b2 ,..., BN> is a pair of sequences L = <A1, A2 ,..., An> sort the sequence in ascending order. Obviously, the longest common subsequence of x and L is the longest ascending subsequence of L. In this way, the problem of finding the longest incrementing subsequence is transformed into finding the longest public subsequence problem LCS.

The longest common subsequence problem can be solved using the dynamic programming algorithm. You can refer to the analysis of this question.

 

2. General DP, O (n2)

(1) memory-based search solution DP

① Forward planning from the back

D (I) indicates the length of the longest incrementing sub-sequence with AI as the last element in L

D [I] = max {dj + 1 | ai> AJ, j <I };

Int A [maxn]; // element <br/> int d [maxn]; // status <br/> int vis [maxn]; // perform a memory search, access tag group <br/> int dp (INT cur) <br/>{< br/> // no conditions for stopping, the corresponding I cannot be found. <br/> If (vis [cur]) return d [cur]; <br/> vis [cur] = 1; <br/> int max = 1; // if no corresponding I is found, the minimum I value is 1 (LIS ). <Br/> for (INT I = 0; I <cur; I ++) if (a [cur]> A [I]) // A [cur]> A [I] | 0 <= I <cur <br/> {<br/> int T = dp (I) + 1; <br/> max = max> T? MAX: T; // Max updated to max {di + 1} <br/>}< br/> return d [cur] = max; <br/>}< br/> int main () <br/> {<br/> memset (VIS, 0, sizeof (VIS )); <br/> int ans = 0; <br/> for (INT I = 0; I <n; I ++) // ANS is the largest D value <br/> ans = ans> dp (I )? Ans: dp (I); <br/>}

② Planning from front to back
Search from the beginning to the back, but Di is the former element. Note the difference in the mark (*).

D [I] = max {dj + 1 | AI <AJ, j = I + 1 ~ N-1 };

In some cases, this plan will be used. For example, the longest increment or decrement subsequence question that has been done must be first added at the beginning.

Int dp (INT cur) <br/>{< br/> If (vis [cur]) return d [cur]; <br/> vis [cur] = 1; <br/> int max = 1; // if no corresponding I is found, the minimum I value is 1 (LIS ). <Br/> for (INT I = cur + 1; I <n; I ++) if (a [cur] <A [I]) //! Traverse the following elements in sequence --------- (*) <br/>{< br/> int T = dp (I) + 1; <br/> max = max> T? MAX: T; <br/>}< br/> return d [cur] = max; <br/>}

(2) incremental solution to DP
We traverse the entire sequence in sequence, and find the longest ascending subsequence from the first number to the current number each time,
Until the last number is traversed, and then the largest in the D array is the longest ascending subsequence of the entire sequence.
We use d [I] to store the sequence 0 ~ The length of the longest ascending subsequence of the I-1, then d [I] = max {d [J]) + 1 | A [I]> A [J], J, [0, i-1]}.
Obviously, d [0] = 1. We can traverse the following elements from I = 1.

Int Lis () <br/>{< br/> memset (D, 0, sizeof (d); <br/> d [0] = 1; <br/> for (INT I = 1; I <n; I ++) // d [I] <br/>{< br/> int max = 0; // here, Max is initialized to 0 instead of 1 to perform d [I] = MAX + 1 in a unified manner. For the operation, see (1) <br/> for (Int J = 0; j <I; j ++) if (a [I]> A [J]) // A [I]> A [J], J, [0, I-1] <br/>{< br/> max = max> d [J]? MAX: d [J]; <br/>}< br/> d [I] = MAX + 1; // ---------- (1 ). <Br/>}< br/> int ans = 0; <br/> for (INT I = 0; I <n; I ++) <br/> ans = ans> d [I]? Ans: d [I]; <br/> return ans; <br/>}

 

Iii. Lis O (nlogn) Algorithm

 

Step 1
In the above algorithm, we need to find the largest d [J] (j <I, AJ <AI) when calculating d [I.
Because the D array is unordered, only the satisfied d [J] can be queried sequentially.
Binary search can be used to reduce the algorithm complexity to O (nlogn ).
Therefore, F (d [I]) = A [I]. indicates that the minimum end element of a subsequence with a length of d [I] is a [I].
Then the problem is solved as the final updated F subscript (maximum length ).
Obviously, F is incremental.
In the above algorithm, if you want to find the largest d [J], you only need to use the Binary Search Method in F.
Find the largest J that satisfies j <I and f [d [J] = AJ <AI. (F [d [J] + 1]> A [I].)
Then, set f [d [J] + 1] to AI, that is, F [d [I] = A [I].
Note that here, is it d [I] = max {d [J] + 1!
For proof refer here (http://www.bccn.net/Article/kfyy/vc/jszl/200709/6258.html ).
Step 2
So, remove array d
Note that f [k] is the minimum value of the last number of the longest sequence with K length.
The following references the code of two others, which is essentially the same:


During binary search, F content is always updated, and the total length of B is K.
If 1. A [I]> = f [K], F [k + 1] = A [I];
If 2. A [I] <F [K], the minimum value greater than a [I] is searched in F [1. K] using binary search, and the position POS is returned,
Then update B [POS] = A [I].

Int bsearch (INT num, int K) <br/>{< br/> int low = 1, high = K; <br/> while (low <= high) <br/>{< br/> int mid = (low + high)/2; <br/> If (Num> = B [Mid]) <br/> low = Mid + 1; <br/> else <br/> high = mid-1; <br/>}< br/> return low; <br/>}< br/> int Lis () <br/>{< br/> int low = 1, high = N; <br/> int K = 1; <br/> B [1] = P [1]; <br/> for (INT I = 2; I <= N; ++ I) <br/> {<br/> If (P [I]> = B [k]) <br/> B [++ K] = P [I]; <br/> else <br/> {<br/> int Pos = bsearch (P [I], k ); <br/> B [POS] = P [I]; <br/>}< br/> return K; <br/>}


When calculating d (I), use the Binary Search Method in array F to find the largest J that satisfies j <I and f [D (j)] = AJ <AI, set f [d [J] + 1] to AI.

Java:
Lis1 (float [] l) <br/>{< br/> int n = L. length; <br/> float [] B = new float [n + 1]; // array B; <br/> B [0] =-10000; // Set B [0] to the minimum value. If any input is greater than-10000, <br/> B [1] = L [0]; // At the initial time, the last element whose maximum incrementing sub-sequence length is 1 is A1 <br/> int Len = 1; // Len is the current maximum incrementing sub-sequence length, initialized to 1; <br/> int P, R, M; // P, R, and m are the upper bound, lower bound, and middle vertex of the binary search, respectively. <br/> for (INT I = 1; I <n; I ++) <br/>{< br/> P = 0; r = Len; <br/> while (P <= r) // binary search for the largest ascending subsequence with the last element smaller than the length of AI + 1; <br/>{< br/> M = (p + r)/2; <br/> If (B [m] <L [I]) P = m + 1; <br/> else r = m-1; <br/>}< br/> B [p] = L [I]; // set the current last element of the maximum incrementing subsequence with a length of P to Ai + 1; <br/> If (P> Len) Len ++; // update the length of the currently largest incrementing subsequence. <br/>}< br/> system. out. println (LEN); <br/>}

 

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.