Given a string S of length N, the task is to find the lexicographically smallest K-length subsequence from the string S (where K < N).
Examples:
Input: S = “bbcaab”, K = 3
Output: “aab”
Input: S = “aabdaabc”, K = 3
Output: “aaa”
Naive Approach: The simplest approach is to generate all possible subsequences of length K from the given string and store all subsequences in a vector. Now, sort the vector and print the string at 0th position for lexicographically the smallest subsequence.
Time Complexity: O(2N)
Auxiliary Space: O(1)
Efficient Approach: To optimize the above approach, the idea is Stack Data Structure to keep track of characters in increasing order, to get the lexicographically smallest subsequence. Follow the steps below to solve the problem:
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void smallestSubsequence(string& S, int K)
{
int N = S.size();
stack< char > answer;
for ( int i = 0; i < N; ++i) {
if (answer.empty()) {
answer.push(S[i]);
}
else {
while ((!answer.empty())
&& (S[i] < answer.top())
&& (answer.size() - 1 + N - i >= K)) {
answer.pop();
}
if (answer.empty() || answer.size() < K) {
answer.push(S[i]);
}
}
}
string ret;
while (!answer.empty()) {
ret.push_back(answer.top());
answer.pop();
}
reverse(ret.begin(), ret.end());
cout << ret;
}
int main()
{
string S = "aabdaabc" ;
int K = 3;
smallestSubsequence(S, K);
return 0;
}
|
Java
import java.util.*;
class GFG
{
static void smallestSubsequence( char []S, int K)
{
int N = S.length;
Stack<Character> answer = new Stack<>();
for ( int i = 0 ; i < N; ++i) {
if (answer.isEmpty()) {
answer.add(S[i]);
}
else {
while ((!answer.isEmpty())
&& (S[i] < answer.peek())
&& (answer.size() - 1 + N - i >= K)) {
answer.pop();
}
if (answer.isEmpty() || answer.size() < K) {
answer.add(S[i]);
}
}
}
String ret= "" ;
while (!answer.isEmpty()) {
ret+=(answer.peek());
answer.pop();
}
ret = reverse(ret);
System.out.print(ret);
}
static String reverse(String input) {
char [] a = input.toCharArray();
int l, r = a.length - 1 ;
for (l = 0 ; l < r; l++, r--) {
char temp = a[l];
a[l] = a[r];
a[r] = temp;
}
return String.valueOf(a);
}
public static void main(String[] args)
{
String S = "aabdaabc" ;
int K = 3 ;
smallestSubsequence(S.toCharArray(), K);
}
}
|
Python3
def smallestSubsequence(S, K):
N = len (S)
answer = []
for i in range (N):
if ( len (answer) = = 0 ):
answer.append(S[i])
else :
while ( len (answer) > 0 and (S[i] < answer[ len (answer) - 1 ]) and ( len (answer) - 1 + N - i > = K)):
answer = answer[: - 1 ]
if ( len (answer) = = 0 or len (answer) < K):
answer.append(S[i])
ret = []
while ( len (answer) > 0 ):
ret.append(answer[ len (answer) - 1 ])
answer = answer[: - 1 ]
ret = ret[:: - 1 ]
ret = ''.join(ret)
print (ret)
if __name__ = = '__main__' :
S = "aabdaabc"
K = 3
smallestSubsequence(S, K)
|
C#
using System;
using System.Collections.Generic;
public class GFG
{
static void smallestSubsequence( char []S, int K)
{
int N = S.Length;
Stack< char > answer = new Stack< char >();
for ( int i = 0; i < N; ++i) {
if (answer.Count==0) {
answer.Push(S[i]);
}
else {
while ((answer.Count!=0)
&& (S[i] < answer.Peek())
&& (answer.Count - 1 + N - i >= K)) {
answer.Pop();
}
if (answer.Count==0 || answer.Count < K) {
answer.Push(S[i]);
}
}
}
String ret= "" ;
while (answer.Count!=0) {
ret+=(answer.Peek());
answer.Pop();
}
ret = reverse(ret);
Console.Write(ret);
}
static String reverse(String input) {
char [] a = input.ToCharArray();
int l, r = a.Length - 1;
for (l = 0; l < r; l++, r--) {
char temp = a[l];
a[l] = a[r];
a[r] = temp;
}
return String.Join( "" ,a);
}
public static void Main(String[] args)
{
String S = "aabdaabc" ;
int K = 3;
smallestSubsequence(S.ToCharArray(), K);
}
}
|
Javascript
<script>
function reverse(input) {
a = input;
var l, r = a.length - 1;
for (l = 0; l < r; l++, r--) {
var temp = a[l];
a[l] = a[r];
a[r] = temp;
}
return a;
}
function smallestSubsequence(S, K)
{
var N = S.length;
answer = [];
for ( var i = 0; i < N; ++i) {
if (answer.length==0) {
answer.push(S[i]);
}
else {
while ((answer.length != 0) && (S[i] < answer[answer.length-1])
&& (answer.length - 1 + N - i >= K)) {
answer.pop();
}
if (answer.length==0 || answer.length < K) {
answer.push(S[i]);
}
}
}
var ret = [];
while (answer.length != 0) {
ret += answer[answer.length -1];
answer.pop();
}
reverse(ret);
document.write(ret);
}
var S = "aabdaabc" ;
var K = 3;
smallestSubsequence(S, K);
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!