I have a sequence of integers {a1,a2...an} and I want to divide it into minimum number of "increasing subsequences". For example: let the sequence be {10,30,20,40}, then the answer would be 2. In this case, the first increasing sequence would be {10,30,40} and the second would be {20}. I am able to do it using an O(N^2) algorithm but I'm particularly interested in an O(N*logN) solution which could serve the purpose.
This could be done with simple greedy algorithm.
Keep sorted array of subsequences found so far. Sorted in decreasing order, by the value of the last integer in each sequence. Initially empty.
Get first not-yet-processed element from the sequence and find the subsequence where the last integer is smaller than this element but larger (or equal) than in all such subsequences. Use binary search here to get overall complexity O(N log N). If no such subsequence found, add a new one at the end of the array. Add this element to this subsequence. Repeat while there are not-yet-processed elements in the sequence.
Related
Given an array of integers. I want to design a comparison-based algorithm
that pairs the largest element with the smallest one, the second largest one with the second smallest one and so on. Obviously, this is easy if I sort the array, but I want to do it in O(n) time. How can I possibly solve this problem?
Well i can prove that it does not exists.
Let`s proof by contradiction: suppose there was such algorithm
When we could get an array of kth min and kth max pairs.
We could when get sorted array by taking all mins in order then all max in order,
so we could get original array sorted in O(n) steps.
So we could get a comparision based sorting algorithm that sorts in O(n)
Yet it can be proven that comparision based sorting algorithm must take atleast n
log n steps. (many proofs online. i.e. https://www.geeksforgeeks.org/lower-bound-on-comparison-based-sorting-algorithms/)
Hence we have a contradiction so such algortihm does not
exist.
How to find the difference between the last and first element of the longest increasing sub-sequence such that value of (last element - first element) in LIS is maximum ?
Let's use a standard dynamic programming solution where we define f[i] as the longest increasing subsequence ending in the i-th element. We can store a pair (max length, smallest first element) for each i instead. One can show that it leads to a correct global solution (intuitively, it's correct as it still stores an optimal solution for all subsequences ending in a specific element and the fact that one prefix is "better" than the other means that the overall subsequence is better).
You can also make it O(N log N) by storing this pairs in an efficient data structure (like a segment tree) if the performance requirements are high.
Very naive algorithm is as follows:
In the first pass find all maximal consecutive subsequences and their length maintain the maximum length (just maintain the number for this).
In the second pass find the start and end differences of all sequences of maximum length and output the one which is maximum among all of them.
All this is in O (n), it is possible to do it in one pass. Just to simplify it I break it down into two steps.
If more than two subarrays exist we need to return the subarray that has lesser length.
We are only concerned with length of the subarray and its sum.
I know this can be solved in O(n^2) using brute force ,but i am looking for a efficient way to do this.
I also tried solving this in O(n) using the sliding window concept , but i later realized it fails for some cases.
How can this be done efficiently?
I would suggest you to look at Kadane's algorithm. It finds a contiguous subarray with the largest sum from a given array. It does so in O(n). Your problem restrains the length to "k". So you simply need to put a check for length <= k in Kadane's.
Assume that we're given a set of pairs S={(x_1,y_1),...,(x_n,y_n)} of integers. What is the most efficient way of computing a maximal sequence of elements (a_1,b_1),...,(a_m,b_m) in S with the property that
a_i <= a_{i+1}
b_i <= b_{i+1}
for i=1,...,m-1, i.e. the sequence is ordered with respect to both components. I can come up with a quadratic algorithm that does the following:
We sort the elements of S with respect to the first coordinate, giving (c_1,d_1),...,(c_n,d_n), where c_i <= c_{i+1}.
Using dynamic programming, for each (c_i,d_i) we compute the longest sequence ordered with respect to both components that ends in (c_i,d_i). This can be done in linear time, once we know the longest such sequence for (c_1,d_1)...,(c_{i+1},d_{i+1}).
Since we have to perform an O(nlogn) sort in step 1 and a linear search for each index in step 2, which is quadratic, we end up with a quadratic runtime.
I've been trying to figure out whether there's a faster, i.e. O(nlogn) way of generating the maximal sequence from having two sorts of the set S: one with respect to the first component, and one with respect to the second. Is this possible?
Yes, it is possible to do it O(n log n).
Let's sort the elements of the set in lexicographical order. The first components are ordered correctly now, so we can forget about them.
Let's take a look at any sorted subsequence of this sorted sequence. The second elements form an increasing subsequence. That's why we can just find the longest increasing subsequence in the sorted sequence for the second element of each pair(completely ignoring first elements as they are already sorted properly). The longest increasing subsequence for an array of numbers can be found in O(n log n) time(it is a well-known problem).
I've seen some discussion about longest monotonically increasing sub-sequence algorithm. But my case is a little bit different.
The double increasing sub-sequence is defined as this:
The first part and second part of the sub-sequence are both monotonically increasing sub-sequences.
For example:
the sequence 10,19,8,12 is;
the sequence 10,19,28,33 is;
the sequence 10,19,28,28 is;
the sequence 10,19,8,2 not;
the sequence 10,19,8,8 not
another sequence that satisfy the condition is:
1,3,5,7,9,10, 6,9,11,17,28,30;
so the first part 1,3,5,7,9,10 is strictly monotonically increasing; and the same for the second part 6,9,11,17,28,30.
The original sequence maybe something like:
1,99,3,98,5,97,7,96,9,95,10, 6,89,9,88,11,87,17,86,28,85,30
Can we find a little-o(n^2)-time algorithm?
Yes, it is even possible to get an O(n log n) solution. Let's assume that we have computed the length of the longest increasing subsequence that ends somewhere to the left(inclusively) from i for each i and the length of the longest decreasing subsequence in a reversed array that to the right from i(not including i). Then the answer is the lagrest sum of these two values for all i. It can be done in O(n log n) time because all what you have to do is to run standard algorithm for computing the longest increasing/decreasing subsequence twice and then make a couple of linear passes.