Given a string s of size n. In one move you can take any subsequence of the given string and add it to the set S. The set S can’t contain duplicates. The move costs n−|t|, where |t| is the length of the added subsequence. The task is to find out the minimum possible total cost to obtain a set S of size k.
Example:
Input: n = 4, k = 5, s = “asdf”
Output: 4Input: n = 5, k = 6, s = aaaaa
Output: 15
Approach:
This problem can be approached using Breadth-First Search (BFS). Consider each string as a vertex in the graph, and there exists a directed edge from string s to string t if and only if t can be obtained from s by removing exactly one character.
In this context, the goal is to find the first k visited vertices when starting the BFS from the initial string. The minimum total cost is then calculated as nk minus the sum of the lengths of the visited strings. It is essential to use a queue of strings instead of integers for BFS, and maintain a set of visited strings instead of an array of visited vertices. The BFS process should terminate when exactly k strings are obtained.
If the number of distinct subsequences is less than k, the answer is -1.
Follow the steps to solve the above problem:
- Initialize the variable ans to 0.
- Create a queue of strings (q) for BFS.
- Create a set of strings (st) to keep track of visited strings.
- Push the initial string s to the queue and mark it as visited in the set.
-
Breadth-First Search (BFS):
-
While the queue is not empty and the set size is less than k:
- Pop the front string (v) from the queue.
-
For each character in the string:
- Create a new string by removing the character.
-
If the new string is not visited and the set size is less than k:
- Push the new string to the queue, mark it as visited, and update ans.
-
While the queue is not empty and the set size is less than k:
- If the set size is less than k, output -1.
- Otherwise, output the final value of ans.
Below is the implementation of the above approach:
#include <bits/stdc++.h> using namespace std;
int main()
{ // input
int n = 4, k = 5;
string s = "asdf" ;
// Initialize the answer variable to 0
int ans = 0;
// Initialize a queue of strings for BFS
queue<string> q;
// Initialize a set to keep track of visited strings
set<string> st;
// Push the initial string to the queue and mark it as
// visited
q.push(s);
st.insert(s);
// Perform BFS until either the queue is empty or the
// set size reaches k
while (!q.empty() && int (st.size()) < k) {
// Retrieve the front string from the queue
string v = q.front();
q.pop();
// Iterate through each character of the string
for ( int i = 0; i < int (v.size()); ++i) {
// Create a new string by removing the i-th
// character
string nv = v;
nv.erase(i, 1);
// Check if the new string is not visited and
// the set size is less than k
if (!st.count(nv) && int (st.size()) + 1 <= k) {
// Push the new string to the queue, mark it
// as visited, and update the answer
q.push(nv);
st.insert(nv);
ans += n - nv.size();
}
}
}
// Check if the set size is less than k and output the
// result
if ( int (st.size()) < k)
cout << -1 << endl;
else
cout << ans << endl;
return 0;
} |
// Java code for the above approach import java.util.*;
class GFG {
public static void main(String[] args)
{
// input
int n = 4 , k = 5 ;
String s = "asdf" ;
// Initialize the answer variable to 0
int ans = 0 ;
// Initialize a queue of strings for BFS
Queue<String> q = new LinkedList<>();
// Initialize a set to keep track of visited strings
Set<String> st = new HashSet<>();
// Push the initial string to the queue
// and mark it as visited
q.add(s);
st.add(s);
// Perform BFS until either the queue is
// empty or the set size reaches k
while (!q.isEmpty() && st.size() < k) {
// Retrieve the front string from the queue
String v = q.poll();
// Iterate through each character of the string
for ( int i = 0 ; i < v.length(); ++i) {
// Create a new string by removing the i-th
// character
String nv = v;
nv = nv.substring( 0 , i)
+ nv.substring(i + 1 );
// Check if the new string is not visited
// and the set size is less than k
if (!st.contains(nv)
&& (st.size() + 1 ) <= k) {
// Push the new string to the queue,
// mark it as visited, and update the
// answer
q.add(nv);
st.add(nv);
ans += n - nv.length();
}
}
}
// Check if the set size is less than
// k and output the result
if (st.size() < k)
System.out.println(- 1 );
else
System.out.println(ans);
}
} // This code is contributed by ragul21 |
from queue import Queue
# Perform BFS to find k distinct strings def find_k_strings(n, k, s):
# Initialize the answer variable to 0
ans = 0
# Initialize a queue of strings for BFS
q = Queue()
# Initialize a set to keep track of visited strings
st = set ()
# Push the initial string to the queue and mark it as visited
q.put(s)
st.add(s)
# Perform BFS until either the queue is empty or the set size reaches k
while not q.empty() and len (st) < k:
# Retrieve the front string from the queue
v = q.get()
# Iterate through each character of the string
for i in range ( len (v)):
# Create a new string by removing the i-th character
nv = v[:i] + v[i + 1 :]
# Check if the new string is not visited and the set size is less than k
if nv not in st and len (st) + 1 < = k:
# Push the new string to the queue, mark it as visited, and update the answer
q.put(nv)
st.add(nv)
ans + = n - len (nv)
# Check if the set size is less than k and output the result
if len (st) < k:
print ( - 1 )
else :
print (ans)
# Input n = 4
k = 5
s = "asdf"
# Call the function find_k_strings(n, k, s) |
using System;
using System.Collections.Generic;
class GFG {
public static void Main ( string [] args) {
// input
int n = 4, k = 5;
string s = "asdf" ;
// Initialize the answer variable to 0
int ans = 0;
// Initialize a queue of strings for BFS
Queue< string > q = new Queue< string >();
// Initialize a set to keep track of visited strings
HashSet< string > st = new HashSet< string >();
// Push the initial string to the queue and mark it as
// visited
q.Enqueue(s);
st.Add(s);
// Perform BFS until either the queue is empty or the
// set size reaches k
while (q.Count > 0 && st.Count < k) {
// Retrieve the front string from the queue
string v = q.Dequeue();
// Iterate through each character of the string
for ( int i = 0; i < v.Length; ++i) {
// Create a new string by removing the i-th
// character
string nv = v.Remove(i, 1);
// Check if the new string is not visited and
// the set size is less than k
if (!st.Contains(nv) && st.Count + 1 <= k) {
// Push the new string to the queue, mark it
// as visited, and update the answer
q.Enqueue(nv);
st.Add(nv);
ans += n - nv.Length;
}
}
}
// Check if the set size is less than k and output the
// result
if (st.Count < k)
Console.WriteLine(-1);
else
Console.WriteLine(ans);
}
} |
class Queue { constructor() {
this .items = [];
}
enqueue(item) {
this .items.push(item);
}
dequeue() {
if ( this .isEmpty()) {
return null ;
}
return this .items.shift();
}
isEmpty() {
return this .items.length === 0;
}
} // Perform BFS to find k distinct strings function findKStrings(n, k, s) {
// Initialize the answer variable to 0
let ans = 0;
// Initialize a queue of strings for BFS
let q = new Queue();
// Initialize a set to keep track of visited strings
let st = new Set();
// Push the initial string to the queue and mark it as visited
q.enqueue(s);
st.add(s);
// Perform BFS until either the queue is empty or the set size reaches k
while (!q.isEmpty() && st.size < k) {
// Retrieve the front string from the queue
let v = q.dequeue();
// Iterate through each character of the string
for (let i = 0; i < v.length; i++) {
// Create a new string by removing the i-th character
let nv = v.slice(0, i) + v.slice(i + 1);
// Check if the new string is not visited and
// the set size is less than k
if (!st.has(nv) && st.size + 1 <= k) {
// Push the new string to the queue, mark it as visited,
// and update the answer
q.enqueue(nv);
st.add(nv);
ans += n - nv.length;
}
}
}
// Check if the set size is less than k and output the result
if (st.size < k) {
console.log(-1);
} else {
console.log(ans);
}
} // Input let n = 4; let k = 5; let s = "asdf" ;
// Call the function findKStrings(n, k, s); |
4
Time Complexity: O(n*n)
Auxiliary Space: O(n*n)