Given an Array of integers, Find the smallest Lexical subsequence with size k.
EX: Array : [3,1,5,3,5,9,2] k =4
Expected Soultion : 1 3 5 2

- 3
- 2

- 886
- 2
- 11
- 14
-
1[Shreyas Shetty](https://stackoverflow.com/users/11102816) posted an [Answer](https://stackoverflow.com/a/65420286) saying there's a solution to this on https://leetcode.com/problems/find-the-most-competitive-subsequence/ – Scratte Dec 23 '20 at 18:27
6 Answers
The problem can be solved in O(n) by maintaining a double ended queue(deque). We iterate the element from left to right and ensure that the deque always holds the smallest lexicographic sequence upto that point. We should only pop off element if the current element is smaller than the elements in deque and the total elements in deque plus remaining to be processed are at least k.
vector<int> smallestLexo(vector<int> s, int k) {
deque<int> dq;
for(int i = 0; i < s.size(); i++) {
while(!dq.empty() && s[i] < dq.back() && (dq.size() + (s.size() - i - 1)) >= k) {
dq.pop_back();
}
dq.push_back(s[i]);
}
return vector<int> (dq.begin(), dq.end());
}

- 261
- 2
- 11
Here is a greedy
algorithm that should work:
Choose Next Number ( lastChoosenIndex, k ) {
minNum = Find out what is the smallest number from lastChoosenIndex to ArraySize-k
//Now we know this number is the best possible candidate to be the next number.
lastChoosenIndex = earliest possible occurance of minNum after lastChoosenIndex
//do the same process for k-1
Choose Next Number ( lastChoosenIndex, k-1 )
}
Algorithm above is high complexity.
But we can pre-sort
all the array elements paired
with their array index
and do the same process greedily using a single loop.
Since we used sorting complexity still will be n*log(n)

- 444
- 1
- 4
- 18
-
This makes sense but isn't there a dynamic programming approach to this solution? – curious_cat Mar 02 '16 at 02:55
-
1look here expected sequence size `k` is fixed. And you want lex smallest of that size. Any dynamic programming approach i think is high complexity and basically ends up doing what the greedy approach does. – Obaida.Opu Mar 02 '16 at 06:54
Ankit Joshi's answer works. But I think it can be done with just a vector itself, not using a deque as all the operations done are available in vector too. Also in Ankit Joshi's answer, the deque can contain extra elements, we have to manually pop off those elements before returning. Add these lines before returning.
while(dq.size() > k)
{
dq.pop_back();
}

- 85
- 1
- 6
It can be done with RMQ in O(n) + Klog(n). Construct an RMQ in O(n). Now find the sequence where every ith element will be the smallest no. from pos [x(i-1)+1 to n-(K-i)] (for i [1 to K] , where x0 = 0, xi is the position of the ith smallest element in the given array)

- 11
- 2
If I've understood the question right, here's a DP Algorithm that should work but it takes O(NK) time
.
//k is the given size and n is the size of the array
create an array dp[k+1][n+1]
initialize the first column with the maximum integer value (we'll need it later)
and the first row with 0's (keep element dp[0][0] = 0)
now run the loop while building the solution
for(int i=1; i<=k; i++) {
for(int j=1; j<=n; j++) {
//if the number of elements in the array is less than the size required (K)
//initialize it with the maximum integer value
if( j < i ) {
dp[i][j] = MAX_INT_VALUE;
}else {
//last minimum of size k-1 with present element or last minimum of size k
dp[i][j] = minimun (dp[i-1][j-1] + arr[j-1], dp[i][j-1]);
}
}
}
//it consists the solution
return dp[k][n];
The last element of the array contains the solution.

- 684
- 6
- 10
- I suggest you can try use modified merge sort. The place for
- modified is merge part, discard the duplicate value.
- select the smallest four
The complexity is o(n logn) Still thinking whether complexity can be o(n)

- 148
- 1
- 6
-
This solution will never work. Selecting smallest four is not the intention. Selecting lexicographicaly smallest sequence is the intention. As Example: For input `2 1 1 1 9 9 9` selecting `1 9 9 9` is better than `2 1 1 1`. – Obaida.Opu Mar 02 '16 at 06:58