给定一个字符串S组成的N个字符和整数K,一个正的,则任务是找到操作的最小数量需要产生从大小为K的随机字符串临时字符串S和从随机字符串中插入任何固定长度的子序列在随机字符串。如果无法生成字符串S ,则打印“-1” 。
例子:
Input: S = “toffee”, N = 4
Output: 2 tofe
Explanation:
Consider the random string temp as “tofe” which is of length K(= 4) and perform the following steps:
Operation 1: Take a subsequence of length 1 from string temp as ‘f’ and after inserting the subsequence in the string “tofe” modifies the string to “toffe”.
Operation 2: Take a subsequence of length 1 from string temp as ‘e’ and after inserting the subsequence in the string “toffe” modifies the string to “toffee”.
Therefore, the minimum number of operations required is 2.
Input: S = “book”, N = 2
Output: -1
方法:这个问题可以通过使用贪心方法和二分搜索来解决。请按照以下步骤解决此问题:
- 初始化 一个 数组,比如说amount[] ,它存储字符串S的每个字符的频率。
- 使用变量i在范围[0, N – 1] 中迭代,并将数组amount[] 中当前字符的频率增加1 。
- 在字符串S 中查找 count 个唯一字符并将其存储在一个变量中,例如count 。
- 如果计数大于N,则返回-1 。
- 现在,执行二进制搜索以查找结果字符串并执行以下步骤:
- 将两个变量初始化为高为10 5和低为0 。
- 迭代直到(high-low)的值大于1 ,执行以下步骤:
- 将total的值更新为0并将mid 更新为(high + low) / 2 。
- 使用变量i在范围[0, 25] 中迭代,如果amount[i]的值大于0 ,则将总数增加(amounts[i] – 1)/mid + 1 。
- 如果 总数小于等于N ,则将high的值更新为mid 。否则,将low的值更新为mid 。
- 完成上述步骤后,打印high的值并在[0, 25]范围内迭代,并打印结果字符串。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find the minimum number
// of string required to generate
// the original string
void findString(string S, int N)
{
// Stores the frequency of each
// character of String S
int amounts[26];
// Iterate over the range [0, 25]
for (int i = 0; i < 26; i++) {
amounts[i] = 0;
}
// Stores the frequency of each
// character of String S
for (int i = 0; i < S.length(); i++) {
amounts[int(S[i]) - 97]++;
}
int count = 0;
// Count unique characters in S
for (int i = 0; i < 26; i++) {
if (amounts[i] > 0)
count++;
}
// If unique characters is greater
// then N, then return -1
if (count > N) {
cout << "-1";
}
// Otherwise
else {
string ans = "";
int high = 100001;
int low = 0;
int mid, total;
// Perform Binary Search
while ((high - low) > 1) {
total = 0;
// Find the value of mid
mid = (high + low) / 2;
// Iterate over the range
// [0, 26]
for (int i = 0; i < 26; i++) {
// If the amount[i] is
// greater than 0
if (amounts[i] > 0) {
total += (amounts[i] - 1)
/ mid
+ 1;
}
}
// Update the ranges
if (total <= N) {
high = mid;
}
else {
low = mid;
}
}
cout << high << " ";
total = 0;
// Find the resultant string
for (int i = 0; i < 26; i++) {
if (amounts[i] > 0) {
total += (amounts[i] - 1)
/ high
+ 1;
for (int j = 0;
j < ((amounts[i] - 1)
/ high
+ 1);
j++) {
// Generate the subsequence
ans += char(i + 97);
}
}
}
// If the length of resultant
// string is less than N than
// add a character 'a'
for (int i = total; i < N; i++) {
ans += 'a';
}
reverse(ans.begin(), ans.end());
// Print the string
cout << ans;
}
}
// Driver Code
int main()
{
string S = "toffee";
int K = 4;
findString(S, K);
return 0;
}
Java
// Java code for above approach
import java.util.*;
class GFG{
// Function to find the minimum number
// of string required to generate
// the original string
static void findString(String S, int N)
{
// Stores the frequency of each
// character of string S
int[] amounts = new int[26];
// Iterate over the range [0, 25]
for (int i = 0; i < 26; i++) {
amounts[i] = 0;
}
// Stores the frequency of each
// character of string S
for (int i = 0; i < S.length(); i++) {
amounts[(int)(S.charAt(i) - 97)]++;
}
int count = 0;
// Count unique characters in S
for (int i = 0; i < 26; i++) {
if (amounts[i] > 0)
count++;
}
// If unique characters is greater
// then N, then return -1
if (count > N) {
System.out.print("-1");
}
// Otherwise
else {
String ans = "";
int high = 100001;
int low = 0;
int mid, total;
// Perform Binary Search
while ((high - low) > 1) {
total = 0;
// Find the value of mid
mid = (high + low) / 2;
// Iterate over the range
// [0, 26]
for (int i = 0; i < 26; i++) {
// If the amount[i] is
// greater than 0
if (amounts[i] > 0) {
total += (amounts[i] - 1)
/ mid
+ 1;
}
}
// Update the ranges
if (total <= N) {
high = mid;
}
else {
low = mid;
}
}
System.out.print(high + " ");
total = 0;
// Find the resultant string
for (int i = 0; i < 26; i++) {
if (amounts[i] > 0) {
total += (amounts[i] - 1)
/ high
+ 1;
for (int j = 0;
j < ((amounts[i] - 1)
/ high
+ 1);
j++) {
// Generate the subsequence
ans += (char)(i + 97);
}
}
}
// If the length of resultant
// string is less than N than
// add a character 'a'
for (int i = total; i < N; i++) {
ans += 'a';
}
String reverse = "";
int Len = ans.length() - 1;
while(Len >= 0)
{
reverse = reverse + ans.charAt(Len);
Len--;
}
// Print the string
System.out.print(reverse);
}
}
// Driver Code
public static void main(String[] args)
{
String S = "toffee";
int K = 4;
findString(S, K);
}
}
// This code is contributed by target_2.
Python3
# Python3 program for the above approach
# Function to find the minimum number
# of string required to generate
# the original string
def findString(S, N):
# Stores the frequency of each
# character of String S
amounts = [0] * 26
# Stores the frequency of each
# character of String S
for i in range(len(S)):
amounts[ord(S[i]) - 97] += 1
count = 0
# Count unique characters in S
for i in range(26):
if amounts[i] > 0:
count += 1
# If unique characters is greater
# then N, then return -1
if count > N:
print("-1")
# Otherwise
else:
ans = ""
high = 100001
low = 0
# Perform Binary Search
while (high - low) > 1:
total = 0
# Find the value of mid
mid = (high + low) // 2
# Iterate over the range
# [0, 26]
for i in range(26):
# If the amount[i] is
# greater than 0
if amounts[i] > 0:
total += (amounts[i] - 1) // mid + 1
# Update the ranges
if total <= N:
high = mid
else:
low = mid
print(high, end = " ")
total = 0
# Find the resultant string
for i in range(26):
if amounts[i] > 0:
total += (amounts[i] - 1) // high + 1
for j in range((amounts[i] - 1) // high + 1):
ans += chr(i + 97)
# If the length of resultant
# string is less than N than
# add a character 'a'
for i in range(total, N):
ans += 'a'
ans = ans[::-1]
# Print the string
print(ans)
# Driver code
S = "toffee"
K = 4
findString(S, K)
# This code is contributed by Parth Manchanda
C#
// C# program for the above approach
using System;
class GFG{
// Function to find the minimum number
// of string required to generate
// the original string
static void findString(string S, int N)
{
// Stores the frequency of each
// character of string S
int[] amounts = new int[26];
// Iterate over the range [0, 25]
for (int i = 0; i < 26; i++) {
amounts[i] = 0;
}
// Stores the frequency of each
// character of string S
for (int i = 0; i < S.Length; i++) {
amounts[(int)(S[i] - 97)]++;
}
int count = 0;
// Count unique characters in S
for (int i = 0; i < 26; i++) {
if (amounts[i] > 0)
count++;
}
// If unique characters is greater
// then N, then return -1
if (count > N) {
Console.Write("-1");
}
// Otherwise
else {
string ans = "";
int high = 100001;
int low = 0;
int mid, total;
// Perform Binary Search
while ((high - low) > 1) {
total = 0;
// Find the value of mid
mid = (high + low) / 2;
// Iterate over the range
// [0, 26]
for (int i = 0; i < 26; i++) {
// If the amount[i] is
// greater than 0
if (amounts[i] > 0) {
total += (amounts[i] - 1)
/ mid
+ 1;
}
}
// Update the ranges
if (total <= N) {
high = mid;
}
else {
low = mid;
}
}
Console.Write(high + " ");
total = 0;
// Find the resultant string
for (int i = 0; i < 26; i++) {
if (amounts[i] > 0) {
total += (amounts[i] - 1)
/ high
+ 1;
for (int j = 0;
j < ((amounts[i] - 1)
/ high
+ 1);
j++) {
// Generate the subsequence
ans += (char)(i + 97);
}
}
}
// If the length of resultant
// string is less than N than
// add a character 'a'
for (int i = total; i < N; i++) {
ans += 'a';
}
string reverse = "";
int Len = ans.Length - 1;
while(Len >= 0)
{
reverse = reverse + ans[Len];
Len--;
}
// Print the string
Console.Write(reverse);
}
}
// Driver Code
public static void Main()
{
string S = "toffee";
int K = 4;
findString(S, K);
}
}
// This code is contributed by splevel62.
Javascript
2 tofe
时间复杂度: O(N)
辅助空间: O(1)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。