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++
// 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
// 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
<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.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!