Minimize steps to form string S from any random string of length K using a fixed length subsequences
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++
#include <bits/stdc++.h>
using namespace std;
void findString(string S, int K)
{
int amounts[26];
for ( int i = 0; i < 26; i++) {
amounts[i] = 0;
}
for ( int i = 0; i < S.length(); i++) {
amounts[ int (S[i]) - 97]++;
}
int count = 0;
for ( int i = 0; i < 26; i++) {
if (amounts[i] > 0)
count++;
}
if (count > K) {
cout << "-1" ;
}
else {
string ans = "" ;
int high = 100001;
int low = 0;
int mid, total;
while ((high - low) > 1) {
total = 0;
mid = (high + low) / 2;
for ( int i = 0; i < 26; i++) {
if (amounts[i] > 0) {
total += (amounts[i] - 1)
/ mid
+ 1;
}
}
if (total <= K) {
high = mid;
}
else {
low = mid;
}
}
cout << high << " " ;
total = 0;
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++) {
ans += char (i + 97);
}
}
}
for ( int i = total; i < K; i++) {
ans += 'a' ;
}
reverse(ans.begin(), ans.end());
cout << ans;
}
}
int main()
{
string S = "toffee" ;
int K = 4;
findString(S, K);
return 0;
}
|
Java
import java.util.*;
class GFG{
static void findString(String S, int N)
{
int [] amounts = new int [ 26 ];
for ( int i = 0 ; i < 26 ; i++) {
amounts[i] = 0 ;
}
for ( int i = 0 ; i < S.length(); i++) {
amounts[( int )(S.charAt(i) - 97 )]++;
}
int count = 0 ;
for ( int i = 0 ; i < 26 ; i++) {
if (amounts[i] > 0 )
count++;
}
if (count > N) {
System.out.print( "-1" );
}
else {
String ans = "" ;
int high = 100001 ;
int low = 0 ;
int mid, total;
while ((high - low) > 1 ) {
total = 0 ;
mid = (high + low) / 2 ;
for ( int i = 0 ; i < 26 ; i++) {
if (amounts[i] > 0 ) {
total += (amounts[i] - 1 )
/ mid
+ 1 ;
}
}
if (total <= N) {
high = mid;
}
else {
low = mid;
}
}
System.out.print(high + " " );
total = 0 ;
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++) {
ans += ( char )(i + 97 );
}
}
}
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--;
}
System.out.print(reverse);
}
}
public static void main(String[] args)
{
String S = "toffee" ;
int K = 4 ;
findString(S, K);
}
}
|
Python3
def findString(S, N):
amounts = [ 0 ] * 26
for i in range ( len (S)):
amounts[ ord (S[i]) - 97 ] + = 1
count = 0
for i in range ( 26 ):
if amounts[i] > 0 :
count + = 1
if count > N:
print ( "-1" )
else :
ans = ""
high = 100001
low = 0
while (high - low) > 1 :
total = 0
mid = (high + low) / / 2
for i in range ( 26 ):
if amounts[i] > 0 :
total + = (amounts[i] - 1 ) / / mid + 1
if total < = N:
high = mid
else :
low = mid
print (high, end = " " )
total = 0
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 )
for i in range (total, N):
ans + = 'a'
ans = ans[:: - 1 ]
print (ans)
S = "toffee"
K = 4
findString(S, K)
|
C#
using System;
class GFG{
static void findString( string S, int N)
{
int [] amounts = new int [26];
for ( int i = 0; i < 26; i++) {
amounts[i] = 0;
}
for ( int i = 0; i < S.Length; i++) {
amounts[( int )(S[i] - 97)]++;
}
int count = 0;
for ( int i = 0; i < 26; i++) {
if (amounts[i] > 0)
count++;
}
if (count > N) {
Console.Write( "-1" );
}
else {
string ans = "" ;
int high = 100001;
int low = 0;
int mid, total;
while ((high - low) > 1) {
total = 0;
mid = (high + low) / 2;
for ( int i = 0; i < 26; i++) {
if (amounts[i] > 0) {
total += (amounts[i] - 1)
/ mid
+ 1;
}
}
if (total <= N) {
high = mid;
}
else {
low = mid;
}
}
Console.Write(high + " " );
total = 0;
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++) {
ans += ( char )(i + 97);
}
}
}
for ( int i = total; i < N; i++) {
ans += 'a' ;
}
string reverse = "" ;
int Len = ans.Length - 1;
while (Len >= 0)
{
reverse = reverse + ans[Len];
Len--;
}
Console.Write(reverse);
}
}
public static void Main()
{
string S = "toffee" ;
int K = 4;
findString(S, K);
}
}
|
Javascript
<script>
function findString(S, N)
{
let amounts = new Array(26);
for (let i = 0; i < 26; i++) {
amounts[i] = 0;
}
for (let i = 0; i < S.length; i++) {
amounts[S[i].charCodeAt(0) - 97]++;
}
let count = 0;
for (let i = 0; i < 26; i++) {
if (amounts[i] > 0) count++;
}
if (count > N) {
document.write( "-1" );
}
else {
let ans = "" ;
let high = 100001;
let low = 0;
let mid, total;
while (high - low > 1) {
total = 0;
mid = Math.floor((high + low) / 2);
for (let i = 0; i < 26; i++) {
if (amounts[i] > 0) {
total += Math.floor((amounts[i] - 1) / mid + 1);
}
}
if (total <= N) {
high = mid;
} else {
low = mid;
}
}
document.write(high + " " );
total = 0;
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++) {
ans += String.fromCharCode(i + 97);
}
}
}
for (let i = total; i < N; i++) {
ans += "a" ;
}
ans = ans.split( "" ).reverse().join( "" );
document.write(ans);
}
}
let S = "toffee" ;
let K = 4;
findString(S, K);
</script>
|
Time Complexity: O(N), where N is the length of the given string.
Auxiliary Space: O(K), for storing a string of length K.
Last Updated :
11 Oct, 2022
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...