📌  相关文章
📜  仅包含一次所有不同字符的字典序最大子序列

📅  最后修改于: 2022-05-13 01:57:08.724000             🧑  作者: Mango

仅包含一次所有不同字符的字典序最大子序列

给定一个字符串S ,任务是从给定的字符串中找出所有不同字符只能由一次构成的字典序上最大的子序列。

例子:

方法:给定的问题可以使用Stack来解决。这个想法是遍历字符串并将这些字符以字典顺序最大的顺序存储在堆栈中,以便生成结果字符串。请按照以下步骤解决给定的问题:

  • 将字符串S的所有字符的频率存储在一个数组中,比如count[]
  • 初始化一个数组,比如visited[] ,它存储堆栈中是否存在任何字符。
  • 使用变量i遍历给定的字符串S并执行以下步骤:
    • 将数组count[]中字符S[i]的频率减少1
    • 现在,如果字符已经存在于堆栈中,则继续下一次迭代。
    • 否则,检查当前字符是否大于栈顶字符且栈顶字符出现的频率是否大于0 ,然后继续从栈中弹出栈顶元素。
    • 完成上述步骤后,在数组visited[]中添加当前字符并将其标记为已访问。
  • 完成上述步骤后,使用堆栈中的字符生成字符串并打印它的反向以获得字典上最大的子序列。

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
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 st;
 
    // Stores if any alphabet is present
    // in the current stack
    vector 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 st = new Stack();
 
        // 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 st = new Stack();
  
        // 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


输出:
bac

时间复杂度: O(N)
辅助空间: O(N)