Given a string S consisting of N characters and a positive integer K, the task is to find the minimum number of operations required to generate the string S from a random string temp of size K and inserting the subsequence of any fixed length from the random string in the random string. If it is impossible to generate the string S, then print “-1”.
Examples:
Input: S = “toffee”, K = 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”, K = 2
Output: -1
Approach: This problem can be solved by using Greedy Approach and Binary Search. Follow the steps below to solve this problem:
- Initialize an array, say amounts[] that stores the frequency of each character of string S.
- Iterate in the range [0, N – 1] using the variable i and increment the frequency of the current character by 1 in the array amounts[].
- Find count unique characters in the string S and store it in a variable, say, count.
- If the count is greater than N, then return -1.
- Now, perform the Binary Search to find the resultant string and perform the following steps:
- Initialize two variables high as 105 and low as 0.
- Iterate until the value of (high – low) is greater than 1 and perform the following steps:
- Update the value of total as 0 and mid as (high + low) / 2.
- Iterate in the range [0, 25] using the variable i and if the value of amounts[i] is greater than 0, then increment the total by (amounts[i] – 1)/mid + 1.
- If the total is less than equal to N, then update the value of high as mid. Otherwise, update the value of low as mid.
- After completing the above steps, print the value of high and iterate in the range[0, 25], and print the resultant string.
Below is the implementation of the above approach:
// C++ program for the above approach #include <bits/stdc++.h> using namespace std;
// Function to find the minimum number // of string required to generate // the original string void findString(string S, int K)
{ // 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 > K) {
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 <= K) {
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 < K; 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 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 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# 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. |
<script> // Javascript program for the above approach // Function to find the minimum number // of string required to generate // the original string function findString(S, N)
{ // Stores the frequency of each
// character of String S
let amounts = new Array(26);
// Iterate over the range [0, 25]
for (let i = 0; i < 26; i++) {
amounts[i] = 0;
}
// Stores the frequency of each
// character of String S
for (let i = 0; i < S.length; i++) {
amounts[S[i].charCodeAt(0) - 97]++;
}
let count = 0;
// Count unique characters in S
for (let i = 0; i < 26; i++) {
if (amounts[i] > 0) count++;
}
// If unique characters is greater
// then N, then return -1
if (count > N) {
document.write( "-1" );
}
// Otherwise
else {
let ans = "" ;
let high = 100001;
let low = 0;
let mid, total;
// Perform Binary Search
while (high - low > 1) {
total = 0;
// Find the value of mid
mid = Math.floor((high + low) / 2);
// Iterate over the range
// [0, 26]
for (let i = 0; i < 26; i++) {
// If the amount[i] is
// greater than 0
if (amounts[i] > 0) {
total += Math.floor((amounts[i] - 1) / mid + 1);
}
}
// Update the ranges
if (total <= N) {
high = mid;
} else {
low = mid;
}
}
document.write(high + " " );
total = 0;
// Find the resultant string
for (let i = 0; i < 26; i++) {
if (amounts[i] > 0) {
total += Math.floor((amounts[i] - 1) / high + 1);
for (let j = 0; j < Math.floor((amounts[i] - 1) / high + 1); j++) {
// Generate the subsequence
ans += String.fromCharCode(i + 97);
}
}
}
// If the length of resultant
// string is less than N than
// add a character 'a'
for (let i = total; i < N; i++) {
ans += "a" ;
}
ans = ans.split( "" ).reverse().join( "" );
// Print the string
document.write(ans);
}
} // Driver Code let S = "toffee" ;
let K = 4; findString(S, K); // This code is contributed by _saurabh_jaiswal. </script> |
2 tofe
Time Complexity: O(N), where N is the length of the given string.
Auxiliary Space: O(K), for storing a string of length K.