给定一个字符串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 现场工作专业课程和学生竞争性编程现场课程。