Longest ascending subsequence

Source: Internet
Author: User
Problem

Given an array with a length of N, find the longest monotonic auto-incrementing subsequence (not necessarily continuous, but the sequence cannot be messy ). For example, if an array a {5, 6, 7, 1, 2, 8} with a length of 6 is given, the longest monotonic increasing subsequence is {5, 6, 7, 8 }, the length is 4.

 

Solution 1: Longest Common subsequence Method

This problem can be converted to the longest common subsequence problem. For example, if array a {5, 6, 7, 1, 2, 8} In the example, we sort the array to obtain array a' {1, 2, 5, 6, 7, 8 }, find out the longest common subsequences of arrays A and. Obviously, the longest common subsequence here is {5, 6, 7, 8}, that is, the longest incrementing subsequence of the original array. The longest common subsequence algorithm is described in detail in the introduction to algorithms.

Assume that the two sequences are x = {x1, x2 ,..., xm} and Y = {y1, Y2 ,..., YN), and set Z = {Z1, Z2 ,..., ZK} is any LCS of X and Y.

1) if XM = YN, zk = XM = YN, And the Zk-1 is an lcs of the Xm-1 and Yn-1.

2) If XM! = YN, then ZK! = XM contains Z is a Xm-1 and Y gets an LCS.

3) If XM! = YN, then ZK! = YN contains Z is an LCS of x and Yn-1.

 

Solution 2: Dynamic Programming Method (time complexity O (N ^ 2 ))

Set the length of N to {A0, A1, A2 ,... an-1), if the length of the longest incrementing sub-sequence ending with AJ is L (J), then l (j) = {max (L (I )) + 1, I <j and a [I] <A [J]}. That is to say, we need to traverse all the positions I (from 0 to J-1) before J to find the L (I) that satisfies Condition A [I] <A [J ), obtain the value of max (L (I) + 1, that is, L (j. Finally, we traverse all L (j) (from 0 to N-1) and find that the maximum is the largest incremental subsequence. The time complexity is O (n ^ 2 ).

For example, if the given array is {5, 6, 7, 1, 2, 8}, L (0) = 1, L (1) = 2, L (2) = 3, L (3) = 1, L (4) = 2, L (5) = 4. Therefore, the maximum length of the Child sequence increasing in this array is 4, and the sequence is {5, 6, 7, 8 }. The algorithm code is as follows:

CPP Code  
  1. # Include <iostream>
  2. Using namespace STD;
  3. # Define Len (A) (sizeof (a)/sizeof (A [0]) // array Length
  4. Int Lis (INT arr [], int Len)
  5. {
  6. Int longest [Len];
  7. For (INT I = 0; I <Len; I ++)
  8. Longest [I] = 1;
  9. For (Int J = 1; j <Len; j ++ ){
  10. For (INT I = 0; I <j; I ++ ){
  11. If (ARR [J]> arr [I] & longest [J] <longest [I] + 1) {// note that the longest [J] <longest [I] + 1 condition cannot be omitted.
  12. Longest [J] = longest [I] + 1; // calculates the length of the longest incrementing subsequence ending with arr [J ].
  13. }
  14. }
  15. }
  16. Int max = 0;
  17. For (Int J = 0; j <Len; j ++ ){
  18. Cout <"Longest [" <j <"] =" <longest [J] <Endl;
  19. If (longest [J]> MAX) max = longest [J]; // find the maximum value from longest [J ].
  20. }
  21. Return Max;
  22. }
  23. Int main ()
  24. {
  25. Int arr [] = {1, 4, 5, 6, 2, 3, 8}; // test Array
  26. Int ret = Lis (ARR, Len (ARR ));
  27. Cout <"Max increment substring Len =" <RET <Endl;
  28. Return 0;
  29. }

Solution 3: O (nlgn) Algorithm

Suppose there is a sequence d [1 .. 9] = {2, 1, 5, 3, 6, 4, 8, 9, 7}, we can see that its LIS length is 5.
Next, we will try to find it.
We define a sequence B, and then let I = 1 to 9 examine the sequence one by one.
In addition, we use a variable Len to record the maximum number of records.

First, put d [1] In B order, so that B [1] = 2, that is, when there is only 1 digit 2, the minimum end of LIS with a length of 1 is 2. Then Len = 1

Then, Put d [2] in B order, so that B [1] = 1, that is, the minimum end of LIS with a length of 1 is 1, d [1] = 2 is useless. It's easy to understand. Then Len = 1

Then, d [3] = 5, d [3]> B [1], so that B [1 + 1] = B [2] = d [3] = 5, that is to say, the minimum end of LIS with a length of 2 is 5, which is easy to understand. At this time, B [1 .. 2] = 1, 5, Len = 2

Again, d [4] = 3, which is exactly between and 5. It is obviously not suitable to place it at the position of 1, because 1 is smaller than 3, and the minimum end of LIS with a length of 1 should be 1, it is easy to infer that the minimum end of LIS with a length of 2 is 3, so 5 can be eliminated. At this time, B [1 .. 2] = 1, 3, Len = 2

Continue, d [5] = 6, it is behind 3, because B [2] = 3, and 6 is behind 3, so it is easy to know that B [3] = 6, B [1 .. 3] = 1, 3, 6. Is it easy to understand? Len = 3.

6th, d [6] = 4. You can see it is between 3 and 6, so we can replace 6 and get B [3] = 4. B [1 .. 3] = 1, 3, 4, Len continues to be 3

7th, d [7] = 8, it's big, bigger than 4, um. So B [4] = 8. Len becomes 4

8th, d [8] = 9, and B [5] = 9, um. Len continues to increase to 5.

The last one, d [9] = 7, is between B [3] = 4 and B [4] = 8, so we know that the latest B [4] = 7, B [1 .. 5] = 1, 3, 4, 7, 9, Len = 5.

So we know that the LIS length is 5.

Note that this 1, 3, 4, 7, 9 is not Lis, it is only the minimum end of the storage of the corresponding length Lis.With this end, We can insert data one by one. Although the last d [9] = 7 is meaningless for this group of data, if there are two numbers 8 and 9, then we can update 8 to d [5], 9 to d [6], and obtain that the LIS length is 6.

Then we should find one thing: inserting data in B is ordered, and it is replaced without moving-that is, we can use binary search, optimize the insertion time of each number to O (logn )~~~~~ So the time complexity of the algorithm is reduced to O (nlogn )~!

The Code is as follows (array B in the Code starts to store data from position 0 ):

CPP Code  
    1. # Include <stdio. h>
    2. # Include <stdlib. h>
    3. # Include <string. h>
    4. # Define N 9 // Number of array elements
    5. Int array [N] = {2, 1, 6, 3, 5, 4, 8, 7, 9}; // original array
    6. Int B [N]; // an array used in dynamic planning. It is used to record intermediate results. The meaning is ambiguous. For more information, see the blog post.
    7. Int Len; // indicates the number of elements in array B.
    8. Int Lis (int * array, int N); // calculates the length of the longest incrementing sub-sequence and calculates the elements of array B. After array [] loops are completed, the length of B is Len.
    9. Int bisearch (int * B, int Len, int W); // modified Binary Search Algorithm
    10. Int main ()
    11. {
    12. Printf ("Lis: % d \ n", Lis (array, n ));
    13. Int I;
    14. For (I = 0; I <Len; ++ I)
    15. {
    16. Printf ("B [% d] = % d \ n", I, B [I]);
    17. }
    18. Return 0;
    19. }
    20. Int Lis (int * array, int N)
    21. {
    22. Len = 1;
    23. B [0] = array [0];
    24. Int I, Pos = 0;
    25. For (I = 1; I <n; ++ I)
    26. {
    27. If (array [I]> B [len-1]) // insert directly to the end of array B if it is greater than the largest element in array B
    28. {
    29. B [Len] = array [I];
    30. ++ Len;
    31. }
    32. Else
    33. {
    34. Pos = bisearch (B, Len, array [I]); // binary search for the location to be inserted
    35. B [POS] = array [I];
    36. }
    37. }
    38. Return Len;
    39. }
    40. // Modify the binary search algorithm to return the position where the array elements need to be inserted.
    41. Int bisearch (int * B, int Len, int W)
    42. {
    43. Int left = 0, Right = len-1;
    44. Int mid;
    45. While (left <= right)
    46. {
    47. Mid = left + (right-left)/2;
    48. If (B [Mid]> W)
    49. Right = mid-1;
    50. Else if (B [Mid] <W)
    51. Left = Mid + 1;
    52. Else // if this element is found
    53. Return mid;
    54. }
    55. Return left; // if this element does not exist in array B, the position of the element to be inserted is returned.
    56. }

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.