Related Articles

Least count of words required to construct a target String

• Last Updated : 20 Jul, 2021

Given an array of strings, words[] of size M and a string target of size N. The task is to find the minimum number of words required to spell out the string target by cutting individual letters from the collection of words and rearranging them, provided that there are infinite supplies of each word. If it is not possible, print -1.

Examples:

Input: words[] = {“with”, “example”, “science”}, target = “thehat”
Output: 3
Explanation: The target string, “thehat” consists of {‘h’ = 2, ‘t’ = 2, ‘e’ = 1, ‘a’ = 1}.
The two “with” strings are required to get two ‘h’ and two ‘t’ and one “example” string is required to get one ‘e’ and one ‘a’ to form the target string “thehat”.
So, total word required to construct the given target is 3.

Input: words[] = {“notice”, “possible”}, target = “basicbasic”
Output: -1
Explanation: It is not possible to form the given target string.

Approach: The idea is to use backtracking. Follow the steps to solve the problem:

• Declare a 2D array, say countMap[][], where countMap[i][j] stores the count of jth character in ith string.
• Declare an array charAvavilable[26], denoting the current count of available characters.
• Define a recursive function that takes in the current index, i (initially 0) of the string, target as the input.
• If the current count is greater than the overall count, then return. Also, if the current index, i is equal to N, update the overall count and return.
• If there is an occurrence of target[i] in charAvailable[],
• Decrement the occurrence of the character target[i] in charAvailable[].
• Recursively call for index i+1, simultaneously updating count by 1.
• Increment the occurrence of the character target[i] by 1 after the function call for backtracking.
• Otherwise, iterate the countMap[][] to find the occurrence of target[i]. If found then, recursively call the function by updating count by 1 and also perform the backtracking step after the function call.
• Print the minimum number of words required.

Below is the implementation of the above approach:

C++

 `// C++ program of the above approach``#include ``using` `namespace` `std;` `// countMap[][] to store``// count of characters``vector > countMap;` `int` `cnt = INT_MAX;` `// Function to get minimum number of``// stickers for a particular state``void` `count(``int` `curCnt, ``int` `pos, vector<``int``>charAvailable,``           ``string target, vector stickers)``{``    ` `    ``// If an optimal solution is``    ``// already there, return``    ``if` `(curCnt >= cnt)``        ``return``;` `    ``int` `m = stickers.size();``    ``int` `n = target.size();` `    ``// If Target has been constructed``    ``// update cnt and return``    ``if` `(pos == n)``    ``{``        ``cnt = min(cnt, curCnt);``        ``return``;``    ``}` `    ``char` `c = target[pos];` `    ``if` `(charAvailable > 0)``    ``{``        ` `        ``// Update charAvailable[]``        ``charAvailable--;` `        ``// Recursizevely function call``        ``// for (pos + 1)``        ``count(curCnt, pos + 1, charAvailable,``              ``target, stickers);` `        ``// Update charAvailable[]``        ``charAvailable++;``    ``}``    ``else``    ``{``        ``for``(``int` `i = 0; i < m; i++)``        ``{``            ``if` `(countMap[i] == 0)``                ``continue``;` `            ``// Update charAvailable[]``            ``for``(``int` `j = 0; j < 26; j++)``            ``{``                ``charAvailable[j] += countMap[i][j];``            ``}` `            ``// Recursizeve Call``            ``count(curCnt + 1, pos, charAvailable,``                  ``target, stickers);` `            ``// Update charAvailable[]``            ``for``(``int` `j = 0; j < 26; j++)``            ``{``                ``charAvailable[j] -= countMap[i][j];``            ``}``        ``}``    ``}``}` `// Function to find the minimum``// number of stickers``int` `minStickers(vector stickers,``                ``string target)``{``    ` `    ``// Base Case``    ``if` `(target == ``""``)``        ``return` `-1;` `    ``if` `(target.size() == 0)``        ``return` `0;` `    ``if` `(stickers.size() == 0)``        ``return` `-1;` `    ``int` `m = stickers.size();``    ``countMap.resize(m, vector<``int``>(26, 0));``    ` `    ``// Fill the countMap Array``    ``for``(``int` `i = 0; i < stickers.size(); i++)``    ``{``        ``string s = stickers[i];``        ``for``(``char` `c : s)``        ``{``            ``countMap[i]++;``        ``}``    ``}` `    ``// Recusizeve function call to get``    ``// minimum number of stickers``    ``vector<``int``> temp(26);``    ``count(0, 0, temp, target, stickers);` `    ``return` `cnt == INT_MAX ? -1 : cnt;``}` `// Driver Code``int` `main()``{``    ` `    ``// Given Input``    ``vector str = {``"with"``, ``"example"``, ``"science"``};``    ``string target = ``"thehat"``;` `    ``// Function Call``    ``int` `Result = minStickers(str, target);` `    ``// Print the result``    ``cout << Result;``}` `// This code is contributed by mohit kumar 29`

Java

 `// Java program of the above approach``import` `java.io.*;``import` `java.util.*;` `class` `Sol {` `    ``// countMap[][] to store``    ``// count of characters``    ``int``[][] countMap;` `    ``int` `cnt = Integer.MAX_VALUE;` `    ``// Function to find the minimum``    ``// number of stickers``    ``public` `int` `minStickers(String[] stickers``                           ``, String target)``    ``{``        ``// Base Case``        ``if` `(target == ``null``)``            ``return` `-``1``;` `        ``if` `(target.length() == ``0``)``            ``return` `0``;` `        ``if` `(stickers == ``null` `|| stickers.length == ``0``)``            ``return` `-``1``;` `        ``int` `m = stickers.length;``        ``countMap = ``new` `int``[m][``26``];` `        ``// Fill the countMap Array``        ``for` `(``int` `i = ``0``; i < stickers.length; i++) {``            ``String s = stickers[i];``            ``for` `(``char` `c : s.toCharArray()) {``                ``countMap[i]++;``            ``}``        ``}` `        ``// Recursive function call to get``        ``// minimum number of stickers``        ``count(``0``, ``0``, ``new` `int``[``26``], target, stickers);` `        ``return` `cnt == Integer.MAX_VALUE ? -``1` `: cnt;``    ``}` `    ``// Function to get minimum number of``    ``// stickers for a particular state``    ``private` `void` `count(``int` `curCnt, ``int` `pos,``                       ``int``[] charAvailable, String target,``                       ``String[] stickers)``    ``{``        ``// If an optimal solution is``        ``// already there, return``        ``if` `(curCnt >= cnt)``            ``return``;` `        ``int` `m = stickers.length;``        ``int` `n = target.length();` `        ``// If Target has been constructed``        ``// update cnt and return``        ``if` `(pos == n) {``            ``cnt = Math.min(cnt, curCnt);``            ``return``;``        ``}` `        ``char` `c = target.charAt(pos);` `        ``if` `(charAvailable > ``0``) {` `            ``// Update charAvailable[]``            ``charAvailable--;` `            ``// Recursively function call``            ``// for (pos + 1)``            ``count(curCnt, pos + ``1``, charAvailable, target,``                  ``stickers);` `            ``// Update charAvailable[]``            ``charAvailable++;``        ``}``        ``else` `{``            ``for` `(``int` `i = ``0``; i < m; i++) {` `                ``if` `(countMap[i] == ``0``)``                    ``continue``;` `                ``// Update charAvailable[]``                ``for` `(``int` `j = ``0``; j < ``26``; j++) {``                    ``charAvailable[j] += countMap[i][j];``                ``}` `                ``// Recursive Call``                ``count(curCnt + ``1``, pos, charAvailable,``                      ``target, stickers);` `                ``// Update charAvailable[]``                ``for` `(``int` `j = ``0``; j < ``26``; j++) {``                    ``charAvailable[j] -= countMap[i][j];``                ``}``            ``}``        ``}``    ``}``}` `class` `GFG {` `    ``// Driver Code``    ``public` `static` `void` `main(String[] args)``    ``{``        ``Sol st = ``new` `Sol();` `        ``// Given Input``        ``String[] str = { ``"with"``, ``"example"``, ``"science"` `};``        ``String target = ``"thehat"``;` `        ``// Function Call``        ``int` `Result = st.minStickers(str, target);` `        ``// Print the result``        ``System.out.println(Result);``    ``}``}`
Output:
`3`

Time Complexity: O(M*26*2N)
Auxiliary Space: O(M*26)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

My Personal Notes arrow_drop_up