Minimize Set Cost
Last Updated :
28 Jan, 2024
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: 4
Input: 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.
- 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:
C++
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n = 4, k = 5;
string s = "asdf" ;
int ans = 0;
queue<string> q;
set<string> st;
q.push(s);
st.insert(s);
while (!q.empty() && int (st.size()) < k) {
string v = q.front();
q.pop();
for ( int i = 0; i < int (v.size()); ++i) {
string nv = v;
nv.erase(i, 1);
if (!st.count(nv) && int (st.size()) + 1 <= k) {
q.push(nv);
st.insert(nv);
ans += n - nv.size();
}
}
}
if ( int (st.size()) < k)
cout << -1 << endl;
else
cout << ans << endl;
return 0;
}
|
Java
import java.util.*;
class GFG {
public static void main(String[] args)
{
int n = 4 , k = 5 ;
String s = "asdf" ;
int ans = 0 ;
Queue<String> q = new LinkedList<>();
Set<String> st = new HashSet<>();
q.add(s);
st.add(s);
while (!q.isEmpty() && st.size() < k) {
String v = q.poll();
for ( int i = 0 ; i < v.length(); ++i) {
String nv = v;
nv = nv.substring( 0 , i)
+ nv.substring(i + 1 );
if (!st.contains(nv)
&& (st.size() + 1 ) <= k) {
q.add(nv);
st.add(nv);
ans += n - nv.length();
}
}
}
if (st.size() < k)
System.out.println(- 1 );
else
System.out.println(ans);
}
}
|
Python3
from queue import Queue
def find_k_strings(n, k, s):
ans = 0
q = Queue()
st = set ()
q.put(s)
st.add(s)
while not q.empty() and len (st) < k:
v = q.get()
for i in range ( len (v)):
nv = v[:i] + v[i + 1 :]
if nv not in st and len (st) + 1 < = k:
q.put(nv)
st.add(nv)
ans + = n - len (nv)
if len (st) < k:
print ( - 1 )
else :
print (ans)
n = 4
k = 5
s = "asdf"
find_k_strings(n, k, s)
|
C#
using System;
using System.Collections.Generic;
class GFG {
public static void Main ( string [] args) {
int n = 4, k = 5;
string s = "asdf" ;
int ans = 0;
Queue< string > q = new Queue< string >();
HashSet< string > st = new HashSet< string >();
q.Enqueue(s);
st.Add(s);
while (q.Count > 0 && st.Count < k) {
string v = q.Dequeue();
for ( int i = 0; i < v.Length; ++i) {
string nv = v.Remove(i, 1);
if (!st.Contains(nv) && st.Count + 1 <= k) {
q.Enqueue(nv);
st.Add(nv);
ans += n - nv.Length;
}
}
}
if (st.Count < k)
Console.WriteLine(-1);
else
Console.WriteLine(ans);
}
}
|
Javascript
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;
}
}
function findKStrings(n, k, s) {
let ans = 0;
let q = new Queue();
let st = new Set();
q.enqueue(s);
st.add(s);
while (!q.isEmpty() && st.size < k) {
let v = q.dequeue();
for (let i = 0; i < v.length; i++) {
let nv = v.slice(0, i) + v.slice(i + 1);
if (!st.has(nv) && st.size + 1 <= k) {
q.enqueue(nv);
st.add(nv);
ans += n - nv.length;
}
}
}
if (st.size < k) {
console.log(-1);
} else {
console.log(ans);
}
}
let n = 4;
let k = 5;
let s = "asdf" ;
findKStrings(n, k, s);
|
Time Complexity: O(n*n)
Auxiliary Space: O(n*n)
Share your thoughts in the comments
Please Login to comment...