Number of Valid Words for Each Puzzle in C++


Suppose there is a puzzle string, a word is valid if both the following conditions valid −

  • word contains the first letter of puzzle.

  • For each letter in word, that letter is in puzzle.

Suppose if we consider an example that, if the puzzle is like "abcdefg", then valid words are "face", "cabbage" etc; but some invalid words are "beefed" as there is no "a" and "based" as there is "s" which is not present in the puzzle.

We have to find the list of answers, where answer[i] is the number of words in the given word list words that are valid with respect to the puzzle puzzles[i].

So, if the input is like words = ["aaaa","asas","able","ability","actt","actor","access"], puzzles = ["aboveyz","abrodyz","abslute","absoryz","actresz","gaswxyz"], then the output will be [1,1,3,2,4,0], as one valid word for "aboveyz" : "aaaa", one valid word for "abrodyz" : "aaaa", three valid words for "abslute" : "aaaa", "asas", "able", two valid words for "absoryz" : "aaaa", "asas", four valid words for "actresz" : "aaaa", "asas", "actt", "access" and there are no valid words for "gaswxyz" cause none of the words in the list contains letter 'g'.

To solve this, we will follow these steps −

  • Define a function getMask(), this will take s,

  • mask := 0

  • for initialize i := 0, when i < size of s, update (increase i by 1), do −

    • mask := mask OR 2^(s[i] - ASCII of 'a')

  • return mask

  • From the main method do the following −

  • Define an array ans

  • Define one map m

  • for initialize i := 0, when i < size of w, update (increase i by 1), do −

    • word := w[i]

    • mask := 0

    • for initialize j := 0, when j < size of word, update (increase j by 1), do−

      • mask := mask OR getMask(w[i])

    • (increase m[mask] by 1)

  • for initialize i := 0, when i < size of p, update (increase i by 1), do −

    • word := p[i]

    • mask := getMask(word)

    • first := 2^(word[0] - ASCII of 'a')

    • current := mask

    • temp := 0

    • while current > 0, do −

      • if current & first is non-zero, then −

        • current := (current - 1) AND mask

    • insert temp at the end of ans

  • return ans

Let us see the following implementation to get better understanding −

Example

 Live Demo

#include <bits/stdc++.h>
using namespace std;
void print_vector(vector<auto> v){
   cout << "[";
   for(int i = 0; i<v.size(); i++){
      cout << v[i] << ", ";
   }
   cout << "]"<<endl;
}
typedef long long int lli;
class Solution {
   public:
   lli getMask(string s){
      lli mask = 0;
      for(int i =0;i<s.size();i++){
         mask|= 1<<(s[i]-'a');
      }
      return mask;
   }
   vector<int> findNumOfValidWords(vector<string>& w, vector<string>& p) {
      vector <int> ans;
      map <lli, lli > m;
      for(int i =0;i<w.size();i++){
         string word = w[i];
         lli mask = 0;
         for(int j =0;j<word.size();j++){
            mask|= getMask(w[i]);
         }
         m[mask]++;
      }
      for(int i = 0; i<p.size();i++){
         string word = p[i];
         lli mask = getMask(word);
         lli first = 1<<(word[0]-'a');
         lli current = mask;
         lli temp = 0;
         while(current>0){
            if(current & first)temp+=m[current];
            current = (current-1)&mask;
         }
         ans.push_back(temp);
      }
      return ans;
   }
};
main(){
   Solution ob;
   vector<string> v = {"aaaa","asas","able","ability","actt","actor","access"};
   vector<string> v1 = {"aboveyz","abrodyz","abslute","absoryz","actresz","gaswxyz"};
   print_vector(ob.findNumOfValidWords(v,v1));
}

Input

{"aaaa","asas","able","ability","actt","actor","access"},
{"aboveyz","abrodyz","abslute","absoryz","actresz","gaswxyz"}

Output

[1, 1, 3, 2, 4, 0, ]

Updated on: 08-Jun-2020

93 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements