Skip to content
Related Articles

Related Articles

Improve Article
Save Article
Like Article

Lexicographically largest subsequence containing all distinct characters only once

  • Last Updated : 14 Sep, 2021

Given a string S, the task is to find the lexicographically largest subsequence that can be formed using all distinct characters only once from the given string.

Examples:

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

Input: S = ababc
Output: bac
Explanation:
All possible subsequences containing all the characters in S exactly once are {“abc”, “bac”}. The lexicograohically maximum among all the subsequences  is “bac”.



Input: S = “zydsbacab”
Output: zydscab

Approach: The given problem can be solved using Stack. The idea is to traverse the string and store those characters in the stack in lexicographically largest order so as to generate the resultant string. Follow the steps below to solve the given problem:

Below is the implementation of the above approach:

C++




// C++ program for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to find the lexicographically
// largest subsequence consisting of all
// distinct characters of S only once
string lexicoMaxSubsequence(string s, int n)
{
    stack<char> st;
 
    // Stores if any alphabet is present
    // in the current stack
    vector<int> visited(26, 0), cnt(26, 0);
 
    // Findthe number of occurences of
    // the character s[i]
    for (int i = 0; i < n; i++) {
        cnt[s[i] - 'a']++;
    }
    for (int i = 0; i < n; i++) {
 
        // Decrease the character count
        // in remaining string
        cnt[s[i] - 'a']--;
 
        // If character is already present
        // in the stack
        if (visited[s[i] - 'a']) {
            continue;
        }
 
        // if current character is greater
        // than last character in stack
        // then pop the top character
        while (!st.empty() && st.top() < s[i]
               && cnt[st.top() - 'a'] != 0) {
            visited[st.top() - 'a'] = 0;
            st.pop();
        }
 
        // Push the current character
        st.push(s[i]);
        visited[s[i] - 'a'] = 1;
    }
 
    // Stores the resultant string
    string s1;
 
    // Generate the string
    while (!st.empty()) {
        s1 = st.top() + s1;
        st.pop();
    }
 
    // Return the resultant string
    return s1;
}
 
// Driver Code
int main()
{
    string S = "ababc";
    int N = S.length();
    cout << lexicoMaxSubsequence(S, N);
 
    return 0;
}

Java




/*package whatever //do not write package name here */
 
import java.io.*;
import java.util.*;
 
class GFG {
    // Function to find the lexicographically
    // largest subsequence consisting of all
    // distinct characters of S only once
    static String lexicoMaxSubsequence(String s, int n)
    {
        Stack<Character> st = new Stack<Character>();
 
        // Stores if any alphabet is present
        // in the current stack
        int[] visited = new int[26];
        int[] cnt = new int[26];
        for (int i = 0; i < 26; i++) {
            visited[i] = 0;
            cnt[i] = 0;
        }
 
        // Findthe number of occurences of
        // the character s[i]
        for (int i = 0; i < n; i++) {
            cnt[s.charAt(i) - 'a']++;
        }
        for (int i = 0; i < n; i++) {
 
            // Decrease the character count
            // in remaining string
            cnt[s.charAt(i) - 'a']--;
 
            // If character is already present
            // in the stack
            if (visited[s.charAt(i) - 'a'] > 0) {
                continue;
            }
 
            // if current character is greater
            // than last character in stack
            // then pop the top character
            while (!st.empty() && st.peek() < s.charAt(i)
                   && cnt[st.peek() - 'a'] != 0) {
                visited[st.peek() - 'a'] = 0;
                st.pop();
            }
 
            // Push the current character
            st.push(s.charAt(i));
            visited[s.charAt(i) - 'a'] = 1;
        }
 
        // Stores the resultant string
        String s1 = "";
 
        // Generate the string
        while (!st.empty()) {
            s1 = st.peek() + s1;
            st.pop();
        }
 
        // Return the resultant string
        return s1;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        String S = "ababc";
        int N = S.length();
        System.out.println(lexicoMaxSubsequence(S, N));
    }
}
 
// This code is contributed by maddler.

Python3




# Python3 program for the above approach
 
# Function to find the lexicographically
# largest subsequence consisting of all
# distinct characters of S only once
def lexicoMaxSubsequence(s, n):
    st = []
 
    # Stores if any alphabet is present
    # in the current stack
    visited = [0]*(26)
    cnt = [0]*(26)
    for i in range(26):
        visited[i] = 0
        cnt[i] = 0
 
    # Findthe number of occurences of
    # the character s[i]
    for i in range(n):
        cnt[ord(s[i]) - ord('a')]+=1
    for i in range(n):
        # Decrease the character count
        # in remaining string
        cnt[ord(s[i]) - ord('a')]-=1
 
        # If character is already present
        # in the stack
        if (visited[ord(s[i]) - ord('a')] > 0):
            continue
 
        # if current character is greater
        # than last character in stack
        # then pop the top character
        while (len(st) > 0 and ord(st[-1]) < ord(s[i]) and cnt[ord(st[-1]) - ord('a')] != 0):
            visited[ord(st[-1]) - ord('a')] = 0
            st.pop()
 
        # Push the current character
        st.append(s[i])
        visited[ord(s[i]) - ord('a')] = 1
 
    # Stores the resultant string
    s1 = ""
 
    # Generate the string
    while (len(st) > 0):
        s1 = st[-1] + s1
        st.pop()
 
    # Return the resultant string
    return s1
 
S = "ababc"
N = len(S)
print(lexicoMaxSubsequence(S, N))
 
# This code is contributed by decode2207.

C#




// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG {
     
    // Function to find the lexicographically
    // largest subsequence consisting of all
    // distinct characters of S only once
    static string lexicoMaxSubsequence(string s, int n)
    {
        Stack<char> st = new Stack<char>();
  
        // Stores if any alphabet is present
        // in the current stack
        int[] visited = new int[26];
        int[] cnt = new int[26];
        for (int i = 0; i < 26; i++) {
            visited[i] = 0;
            cnt[i] = 0;
        }
  
        // Findthe number of occurences of
        // the character s[i]
        for (int i = 0; i < n; i++) {
            cnt[s[i] - 'a']++;
        }
        for (int i = 0; i < n; i++) {
  
            // Decrease the character count
            // in remaining string
            cnt[s[i] - 'a']--;
  
            // If character is already present
            // in the stack
            if (visited[s[i] - 'a'] > 0) {
                continue;
            }
  
            // if current character is greater
            // than last character in stack
            // then pop the top character
            while (st.Count > 0 && st.Peek() < s[i]
                   && cnt[st.Peek() - 'a'] != 0) {
                visited[st.Peek() - 'a'] = 0;
                st.Pop();
            }
  
            // Push the current character
            st.Push(s[i]);
            visited[s[i] - 'a'] = 1;
        }
  
        // Stores the resultant string
        string s1 = "";
  
        // Generate the string
        while (st.Count > 0) {
            s1 = st.Peek() + s1;
            st.Pop();
        }
  
        // Return the resultant string
        return s1;
    }
     
  static void Main() {
    string S = "ababc";
    int N = S.Length;
    Console.Write(lexicoMaxSubsequence(S, N));
  }
}
 
// This code is contributed by suresh07.

Javascript




<script>
    // Javascript program for the above approach
     
    // Function to find the lexicographically
    // largest subsequence consisting of all
    // distinct characters of S only once
    function lexicoMaxSubsequence(s, n)
    {
        let st = [];
   
        // Stores if any alphabet is present
        // in the current stack
        let visited = new Array(26);
        let cnt = new Array(26);
        for (let i = 0; i < 26; i++) {
            visited[i] = 0;
            cnt[i] = 0;
        }
   
        // Findthe number of occurences of
        // the character s[i]
        for (let i = 0; i < n; i++) {
            cnt[s[i].charCodeAt() - 'a'.charCodeAt()]++;
        }
        for (let i = 0; i < n; i++) {
   
            // Decrease the character count
            // in remaining string
            cnt[s[i].charCodeAt() - 'a'.charCodeAt()]--;
   
            // If character is already present
            // in the stack
            if (visited[s[i].charCodeAt() - 'a'.charCodeAt()] > 0) {
                continue;
            }
   
            // if current character is greater
            // than last character in stack
            // then pop the top character
            while (st.length > 0 && st[st.length - 1].charCodeAt() < s[i].charCodeAt()
                   && cnt[st[st.length - 1].charCodeAt() - 'a'.charCodeAt()] != 0) {
                visited[st[st.length - 1].charCodeAt() - 'a'.charCodeAt()] = 0;
                st.pop();
            }
   
            // Push the current character
            st.push(s[i]);
            visited[s[i].charCodeAt() - 'a'.charCodeAt()] = 1;
        }
   
        // Stores the resultant string
        let s1 = "";
   
        // Generate the string
        while (st.length > 0) {
            s1 = st[st.length - 1] + s1;
            st.pop();
        }
   
        // Return the resultant string
        return s1;
    }
     
    let S = "ababc";
    let N = S.length;
    document.write(lexicoMaxSubsequence(S, N));
     
    // This code is contributed by divyeshrabadiya07.
</script>
Output: 
bac

 

Time Complexity: O(N)
Auxiliary Space: O(N)




My Personal Notes arrow_drop_up
Recommended Articles
Page :