1. Brief Introduction
Write a program with the lowest possible time complexity, and obtain the length of the longest incrementing subsequence in a one-dimensional array.
For example, in sequence 1,-7, the longest length of the incremental subsequence is 4 (such ).
2. Ideas
This question is a bit like the maximum value of the subarray in the one-dimensional array, but the difference is quite obvious. For example, a subarray is a string of consecutive adjacent numbers in the array, the sub-sequence is not necessarily adjacent, so to obtain the largest and largest sub-array of [0-K], as long as the analysis of [0-(k-1)] sub-array is the largest and can, considering the longest length of the subsequence of [0-K], the longest length of [0-(k-1)] neutron sequence cannot be analyzed only. Another difference is that the sub-array and the sub-array can be extended to two-dimensional arrays, but the incremental sub-sequence cannot be extended, so it can be extended to the young triangle at most.
Method 1: calculate each possible sub-sequence, determine whether it is incremental, and then select the largest one. There may be 2 ^ N subsequences, so the complexity is O (2 ^ N ).
Method 2: to determine whether an element can form a longer sub-sequence with an existing sub-sequence, we only need to compare this element with the last element of the sub-sequence, in fact, for the 2 ^ I sub-sequence in [0-(I-1)], we only need to record the length of the longest child sequence that contains each element and ends with this element. That is, MaxLen [I] is defined, which indicates the maximum length of A [I] in the range of A [0]-A [I. In this way, the 2 ^ I subsequence can be represented by the I subsequence.
Recursive Formula: MaxLen [0] = 1, MaxLen [I] = max {A [I]> = A [k]? (MaxLen [k] + 1): 1}, k =, 2,..., I-1.
Finally max {MaxLen [I]}, I =, 2,..., N-1, that is, ask.
In this method, the 2 ^ N neutron sequence is represented by N subsequences (based on the subsequences, you only need to determine the last element of the subsequence ), the complexity is O (N ^ 2 ).
Method 3: method 2 uses the tail element method, from focusing on the 2 ^ N subsequences, to focusing on the N largest headers ending with A [I] respectively. Here we use another ing method. We focus on the sub-sequence with the smallest tail element and the length of the sub-sequence is I. Definition: LenMinValue [I], which indicates the minimum element value at the end of several subsequences with the length of I. MaxLen is the maximum length of the Child sequence currently found.
Recurrence Formula: MaxLen = 1, LenMinValue [0] = INT_MIN (Sentinel), LenMinValue [1] = A [0]. For A [I], locate the position of A [I] in the range of LenMinValue [0]-LenMinValue [MaxLen. If A [I]> LenMinValue [MaxLen], it indicates that the maximum length is to be updated. MaxLen ++, LenMinValue [MaxLen] = A [I]; if LenMinValue [j] <A [I] <LenMinValue [j + 1], 0 <= j <= MaxLen-1 (must be greater than A number because LenMinValue [0] is A sentinel ), this indicates that the Right length subsequence has A smaller tail value, that is, A [I], LenMinValue [Right] = A [I].
Here, we will explain that we have already calculated five elements. The length of the longest subsequence (that is, MaxLen) may only be 1, that is, when all the subsequences are in reverse order, MaxLen = 1 at this time, which will compress a lot. In addition, if MaxLen = 3, there must be LenMinValue [0] <LenMinValue [1] <LenMinValue [2] <LenMinvalue [3]. This is because, A child sequence with a length of 2 is generated by adding an element after the child sequence with a length of 1, the value of this element must be at least LenMinValue [2] (at least because multiple subsequences may have a length of 2 and LenMinValue [2] is the minimum value ). That is, LenMinValue [0]-LenMinValue [MaxLen] is ordered. Therefore, when searching for A [I] location, you can use the binary method (the number in the array may change if repeated values are allowed ).
In general, the worst case is O (N * LogN), but it is actually A little smaller, because from A [2], the maximum number of two points each time is Log2 + Log3 + Log4 +... + Log (N-1), of course, is actually smaller, because if the length is increasing, it means that the array is in ascending order, then every second will soon be unable to use the LogK, if the array is not in ascending order, the length will not increase continuously, so the factor in the Log will not increase continuously, and all complexity will be reduced by N * LogN.
3. Code
Code of method 2 and method 3. For simple implementation, method 3 does not add a binary search.
# Include <iostream>
Using namespace std;
Int find_max_len_method2 (const int * A, int N ){
Int * max_len = new int [N]; // max_len [I] indicates the maximum length of the subsequences ending with A [I]
Max_len [0] = 1;
For (int I = 1; I <N; I ++) {// consider the subsequence ending with A [1],..., A [N-1] in sequence
Max_len [I] = 1;
For (int j = 0; j <I; j ++ ){
If (A [I]> A [j]) {
Max_len [I] = max_len [j] + 1> max_len [I]? (Max_len [j] + 1): max_len [I];
}
}
}
Cout <"max_len" <endl;
For (int I = 0; I <N; I ++)
Cout <max_len [I] <"";
Cout <endl;
Int result = 0;
For (int I = 0; I <N; I ++)
Result = max_len [I]> result? Max_len [I]: result;
Delete [] max_len;
Return result;
}
Int find_max_len_method3 (const int * A, int N ){
Int * len_min_value = new int [N + 1];
Int max_len;
Len_min_value [0] = INT_MIN;
Len_min_value [1] = A [0];
Max_len = 1;
For (INT I = 1; I <n; I ++) {// introduce a [1] in sequence,..., a [N-1]
Int Pos = max_len;
If (A [I]> len_min_value [max_len]) {
Max_len ++;
Len_min_value [max_len] = A [I];
}
Else {
Int J = max_len-1;
While (A [I] <len_min_value [J])
J --;
Len_min_value [J + 1] = A [I];
}
}
Cout <"len_min_value" <Endl;
For (INT I = 0; I <n + 1; I ++)
Cout <"D:" <len_min_value [I] <"";
Cout <Endl;
Delete [] len_min_value;
Return max_len;
}
Int main (){
Int A [8] = {1,-1, 2,-3, 4,-5, 6,-7}; // 1, 2, 4, 6
Cout <"array:" <Endl;
For (INT I = 0; I <8; I ++)
Cout <A [I] <"";
Cout <Endl;
Cout <"the maximum length of the ascending sub-sequence of the array is:" <find_max_len_method2 (A, 8) <Endl;
Cout <"the maximum length of the ascending sub-sequence of the array is:" <find_max_len_method3 (A, 8) <Endl;
System ("pause ");
Return 0;
}
Result output:
4. Reference
The beauty of programming, section 2.16, calculates the longest incrementing subsequence in the array