Stickers to Spell Word in C++


Suppose we have N different types of stickers. In each type of sticker has a lowercase English word on it. We would like to spell out the given target string by cutting individual letters from our collection of stickers and rearranging them. We can use each sticker more than once if needed, and we have infinite quantities of each sticker.

We have to find the minimum number of stickers that we need to spell out the target? If the task is impossible, return -1.

So if the input is like [“dog”, “sentence”, ”antenna”], and target is “dance”, then the answer will be 3

To solve this, we will follow these steps −

  • n := size of target
  • N := shift 1 to the left n times
  • Define an array dp of size N initialize it with inf
  • dp[0] := 0
  • for initialize i := 0, when i <N, update (increase i by 1), do −
    • if dp[i] is same as inf, then −
      • Ignore following part, skip to the next iteration
    • for initialize j := 0, when j <size of stickers, update (increase j by 1), do −
      • s := stickers[j]
      • x := i
      • for initialize k := 0, when k <size of s, update (increase k by 1), do −
        • z := s[k]
        • for initialize l := 0, when l < size of target, update (increase l by 1), do −
          • if target[l] is same as z and (right shifting x, l bits ) AND 1) is same as 0, then −
            • x := x OR (shift 1 to the left l bits)
            • Come out from the loop
      • dp[x] := minimum of dp[x] and dp[i] + 1
  • return dp[N - 1] is inf then set with - 1 otherwise set with dp[N - 1]

Let us see the following implementation to get better understanding −

Example

 Live Demo

#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
   int minStickers(vector<string>& stickers, string target) {
      int n = target.size();
      int N = 1 << n;
      vector <int> dp(N, INT_MAX);
      dp[0] = 0;
      for(int i = 0; i < N; i++){
         if(dp[i] == INT_MAX) continue;
         for(int j = 0; j < stickers.size(); j++){
            string s = stickers[j];
            int x = i;
            for(int k = 0; k < s.size(); k++){
               char z = s[k];
               for(int l = 0; l < target.size(); l++){
                  if(target[l] == z && ((x >> l) & 1) == 0){
                     x |= (1 << l);
                     break;
                  }
               }
            }
            dp[x] = min(dp[x], dp[i] + 1);
         }
      }
      return dp[N - 1] == INT_MAX? -1 : dp[N - 1];
   }
};
main(){
   Solution ob;
   vector<string> v = {"dog", "sentence","antenna"};
   cout << (ob.minStickers(v, "dance"));
}

Input

["dog", "sentence","antenna"]
"dance"

Output

3

Updated on: 02-Jun-2020

287 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements