📌  相关文章
📜  字典上最大的子序列,使得每个字符至少出现 k 次

📅  最后修改于: 2021-10-26 06:59:17             🧑  作者: Mango

给定一个字符串S和一个整数K 。任务是找到 S 的字典序最大的子序列,比如 T,使得 T 中的每个字符必须至少出现 K 次。
例子:

Input : S = "banana", K = 2.
Output : nn
Possible subsequence where each character exists at least 2 times are:

From the above subsequences, "nn" is the lexicographically largest.

思路就是贪图解决上面的问题。如果我们想让子序列在字典上最大,我们必须优先使用字典上较大的字符。 ‘z’ 是最大的字符,假设 z 在 S 中出现 f z次。如果 f z >= K,则在字符串T 中追加 ‘z’z k 次并继续从 S 的左侧删除字符,直到所有 z 都出现移除。应用带有“y”、“w”、…..、“a”的策略。最后,你会找到答案。
让我们看一个例子。假设 S = “zzwzawa” 并且 K = 2。从最大的字符’z’ 开始。这里 f z = 3 >= K。所以 T 将变成“zzz”,我们将删除 S 左边的字母,直到所有 z 都被删除。所以现在S会变成“awa”。下一个最大的是 ‘y’ 但它在 k 中出现了 0 次,所以我们将跳过它。我们也将跳过 ‘w’、’v’ 等,直到我们转到出现 2 次的 ‘a’。现在 T 将变为“zzzaa”,S 将变为空字符串。我们的答案是“zzzaa”。
下面是这种方法的实现:

C++
// C++ program to find lexicographically largest
// subsequence where every character appears at
// least k times.
#include 
using namespace std;
 
// Find lexicographically largest subsequence of
// s[0..n-1] such that every character appears
// at least k times. The result is filled in t[]
void subsequence(char s[], char t[], int n, int k)
{
    int last = 0, cnt = 0, new_last = 0, size = 0;
 
    // Starting from largest charter 'z' to 'a'
    for (char ch = 'z'; ch >= 'a'; ch--) {
        cnt = 0;
 
        // Counting the frequency of the character
        for (int i = last; i < n; i++) {
            if (s[i] == ch)
                cnt++;
        }
 
        // If frequency is greater than k
        if (cnt >= k) {
 
            // From the last point we leave
            for (int i = last; i < n; i++) {
 
                // check if string contain ch
                if (s[i] == ch) {
 
                    // If yes, append to output string
                    t[size++] = ch;
                    new_last = i;
                }
            }
 
            // Update the last point.
            last = new_last;
        }
    }
    t[size] = '\0';
}
 
// Driver code
int main()
{
    char s[] = "banana";
    int n = sizeof(s);
    int k = 2;
    char t[n];
    subsequence(s, t, n - 1, k);
    cout << t << endl;
    return 0;
}


Java
import java.util.Arrays;
 
 
// Java program to find lexicographically largest
// subsequence where every character appears at
// least k times. 
class GFG {
 
// Find lexicographically largest subsequence of
// s[0..n-1] such that every character appears
// at least k times. The result is filled in t[]
static void subsequence(char s[], char t[], int n, int k)
{
    int last = 0, cnt = 0, new_last = 0, size = 0;
  
    // Starting from largest charter 'z' to 'a'
    for (char ch = 'z'; ch >= 'a'; ch--) {
        cnt = 0;
  
        // Counting the frequency of the character
        for (int i = last; i < n; i++) {
            if (s[i] == ch)
                cnt++;
        }
  
        // If frequency is greater than k
        if (cnt >= k) {
  
            // From the last point we leave
            for (int i = last; i < n; i++) {
  
                // check if string contain ch
                if (s[i] == ch) {
  
                    // If yes, append to output string
                    t[size++] = ch;
                    new_last = i;
                }
            }
  
            // Update the last point.
            last = new_last;
        }
    }
    t[size] = '\0';
}
  
// Driver code
    public static void main(String[] args) {
    char s[] = {'b','a','n','a','n','a'};
    int n = s.length;
    int k = 2;
    char t[] = new char[n];
    subsequence(s, t, n - 1, k);
    for(int i = 0;i


Python3
# Python3 program to find lexicographically largest
# subsequence where every character appears at
# least k times.
 
# Find lexicographically largest subsequence of
# s[0..n-1] such that every character appears
# at least k times. The result is filled in t[]
def subsequence(s, t, n, k):
    last = 0
    cnt = 0
    new_last = 0
    size = 0
 
    string = 'zyxwvutsrqponmlkjihgfedcba'
 
    # Starting from largest charter 'z' to 'a'
    for ch in string:
        cnt = 0
        for i in range(last, n):
            if s[i] == ch:
                cnt += 1
 
        # If frequency is greater than k
        if cnt >= k:
 
            # From the last point we leave
            for i in range(last, n):
 
                # check if string contain ch
                if s[i] == ch:
 
                    # If yes, append to output string
                    t[size] = ch
                    new_last = i
                    size += 1
 
            # Update the last point.
            last = new_last
 
# Driver Code
if __name__ == "__main__":
    s = ['b', 'a', 'n', 'a', 'n', 'a']
    n = len(s)
    k = 2
    t = [''] * n
    subsequence(s, t, n - 1, k)
    t = ''.join(t)
    print(t)
 
# This code is contributed by
# sanjeev2552


C#
// C# program to find lexicographically
// largest subsequence where every
// character appears at least k times.
using System;
 
class GFG
{
 
// Find lexicographically largest subsequence
// of s[0..n-1] such that every character
// appears at least k times. The result is
// filled in t[]
static void subsequence(char []s, char []t,
                        int n, int k)
{
    int last = 0, cnt = 0,
        new_last = 0, size = 0;
 
    // Starting from largest character
    // 'z' to 'a'
    for (char ch = 'z'; ch >= 'a'; ch--)
    {
        cnt = 0;
 
        // Counting the frequency of
        // the character
        for (int i = last; i < n; i++)
        {
            if (s[i] == ch)
                cnt++;
        }
 
        // If frequency is greater than k
        if (cnt >= k)
        {
 
            // From the last point we leave
            for (int i = last; i < n; i++)
            {
 
                // check if string contain ch
                if (s[i] == ch)
                {
 
                    // If yes, append to output string
                    t[size++] = ch;
                    new_last = i;
                }
            }
 
            // Update the last point.
            last = new_last;
        }
    }
    t[size] = '\0';
}
 
// Driver code
public static void Main()
{
    char []s = {'b','a','n','a','n','a'};
    int n = s.Length;
    int k = 2;
    char []t = new char[n];
    subsequence(s, t, n - 1, k);
    for(int i = 0; i < t.Length; i++)
        if(t[i] != 0)
            Console.Write(t[i]);
}
}
 
// This code contributed by Rajput-Ji


Javascript


输出:

nn

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程