There is a known problem "Longest increasing subsequence", which is: Given an array of integers, find out the longest increasing sequence in that array. I now face a similar but apparently more complicated problem: Given an array of integers and a given number N, find N sequences in that array so that each of them is increasing, they do not intersect by indexes and their combined sum of lengths is maximal.
So far I have tried "greedy" algorithms in the line of:
Use the longest increasing subsequence algorithm, throw that sequence away from the array, repeat N times, provide found sequences as result. This works if N=1 by design, works in several odd cases but returns incorrect results for shuffled arrays such as an array constructed of N increasing subsequences.
Construct a number of sequences, adding each element to the now-longest possible subsequence. Obviously flawed, as it finds "substrings" more often than prolonged sequences.
Construct a number of sequences, adding each element to the sequence that has the largest last element. This works better, at least if an array is known to contain N increasing subsequences, this algorithm correctly returns full array as the result, but it does not work properly in general, as it does not consume N as is.
Any other ideas?
If you want to play with sample data of decent size, here's an array:
103,202,234,260,301,324,356,379,405,412,421,284,137,439,315,150,322,454,185,335,481,208,495,223,358,258,522,267,365,526,
536,374,399,566,580,424,302,602,335,365,618,441,380,455,397,483,510,410,419,622,529,534,633,442,544,568,653,668,474,502,
689,583,607,694,699,530,618,648,654,555,705,723,563,738,672,595,746,697,766,720,624,740,794,798,818,845,859,653,752,758,
783,674,793,805,876,831,892,918,929,689,865,950,874,966,997,716,738,899,759,1023,1032,917,1053,938,944,1080,771,797,
960,1089,980,815,839,850,1110,1011,1115,861,878,1143,901,1025,931,1175,1192,1197,1050,1229,959,988,1058,1008,1038,1088,
1116,1126,1135,1063,1256,1269,1082,1275,1088,1305,1122,1154,1157,1326,1184,1350,1184,1205,1236,1268,1293,1324,1373,1347,
1365,1217,1400,1240,1261,1414,1381,1406,1413,1443,1282,1451,1456,1442,1476,1485,1475,1488,1499,1510,1508,1316,1325,1338,
1540,1536,1353,1556,1558,1588,1363,1587,1617,1382,1625,1402,1609,1415,1633,1642,1655,1671,1689,1697,1439,1712,1458,1732,
1481,1693,1510,1747,1715,1762,1730,1791,1820,1522,1539,1748,1759,1566,1577,1584,1611,1646,1834,1790,1653,1820,1659,1833,
1693,1842,1704,1717,1846,1868,1729,1744,1773,1882,1796,1915,1937,1814,1861,1846,1941,1871,1905,1893,1931,1945,1917,
1960,1979,1941,1960,1980,1933,1962,2014,2046,1975,1988,2008,1988,2040,1995,2062,2000,2009,2025,2083,2058,2067,2083,2103,
2038,2114,2121,2134,2063,2166,2115,2124,2178,2202,2135,2090,2104
This is an array constructed of 3 randomized increasing subsequences with overlapping ranges, each having a length of 100, so processing this array with a proper algorithm with N=3 should return full array, with N=1 the answer should be 123, and for N=2, no less than 222. (True value yet undetermined)
I have an array
A[4]={4,5,9,1}
I need it would give the first 3 top elements like 9,5,4
I know how to find the max element but how to find the 2nd and 3rd max?
i.e if
max=A[0]
for(i=1;i<4;i++)
{
if (A[i]>max)
{
max=A[i];
location=i+1;
}
}
actually sorting will not be suitable for my application because,
the position number is also important for me i.e. I have to know in which positions the first 3 maximum is occurring, here it is in 0th,1th and 2nd position...so I am thinking of a logic
that after getting the max value if I could put 0 at that location and could apply the same steps for that new array i.e.{4,5,0,1}
But I am bit confused how to put my logic in code
Consider using the technique employed in the Python standard library. It uses an underlying heap data structure:
def nlargest(n, iterable):
"""Find the n largest elements in a dataset.
Equivalent to: sorted(iterable, reverse=True)[:n]
"""
if n < 0:
return []
it = iter(iterable)
result = list(islice(it, n))
if not result:
return result
heapify(result)
for elem in it:
heappushpop(result, elem)
result.sort(reverse=True)
return result
The steps are:
Make an n length fixed array to hold the results.
Populate the array with the first n elements of the input.
Transform the array into a minheap.
Loop over remaining inputs, replacing the top element of the heap if new data element is larger.
If needed, sort the final n elements.
The heap approach is memory efficient (not requiring more memory than the target output) and typically has a very low number of comparisons (see this comparative analysis).
You can use the selection algorithm
Also to mention that the complexity will be O(n) ie, O(n) for selection and O(n) for iterating, so the total is also O(n)
What your essentially asking is equivalent to sorting your array in descending order. The fastest way to do this is using heapsort or quicksort depending on the size of your array.
Once your array is sorted your largest number will be at index 0, your second largest will be at index 1, ...., in general your nth largest will be at index n-1
you can follw this procedure,
1. Add the n elements to another array B[n];
2. Sort the array B[n]
3. Then for each element in A[n...m] check,
A[k]>B[0]
if so then number A[k] is among n large elements so,
search for proper position for A[k] in B[n] and replace and move the numbers on left in B[n] so that B[n] contains n large elements.
4. Repeat this for all elements in A[m].
At the end B[n] will have the n largest elements.