Count of strings that contains every String of another Array as Subset
Last Updated :
27 Jul, 2023
Given two arrays of strings A[] and B[] containing only small case letters, the task is to count the number of strings in A[] such that it contains every string of array B[] as a subset (ordering of characters does not matter).
Examples:
Input: A[] = {“geeks”, “gfg”}, B[] = {“g”, “gf”}
Output: 1
Explanation: “gfg” in array A[] is the only string
that has both “g” and “gf”.
Input: A[] = {“geekolymic”, “google”, “amazon”}, B[] = {“og” }
Output: 2
Explanation: “geekolymic” and “google” both contains “og” as subset.
Approach:
The condition for all strings of B to be present as a subset in a string of array A is:
- Maximum frequency of every letter of B ≤ frequency of every letter of B in A[i].
Follow the steps to solve this problem:
- Create a max_freq[] array to store the maximum frequency of each letter in words of B.
- For each word in B, calculate the frequency of each letter in that word and update the max_freq[] array.
- Initialize a variable ans = 0, now for every word in A[], calculate the frequency of each character in a temp[] array.
- For each letter in that word if max_freq[i] <= temp[i], increment the ans.
- Return the ans.
Below is the implementation of the above approach :
C++14
#include <bits/stdc++.h>
using namespace std;
int countcommon(vector<string> A, vector<string> B, int N,
int M)
{
int max_freq[26] = { 0 };
int ans = 0;
for ( int i = 0; i < M; i++) {
int temp[26] = { 0 };
for ( int j = 0; j < B[i].size(); j++) {
temp[B[i][j] - 'a' ]++;
}
for ( int k = 0; k < 26; k++) {
max_freq[k] = max(max_freq[k], temp[k]);
}
}
for ( int i = 0; i < N; i++) {
int temp[26] = { 0 };
for ( int j = 0; j < A[i].size(); j++) {
temp[A[i][j] - 'a' ]++;
}
bool f = false ;
for ( int k = 0; k < 26; k++) {
if (max_freq[k] > temp[k]) {
f = true ;
break ;
}
}
if (f == false )
ans++;
}
return ans;
}
int main()
{
vector<string> A{ "geekolymic" , "google" , "amazon" };
vector<string> B{ "go" };
int N = A.size();
int M = B.size();
cout << countcommon(A, B, N, M) << endl;
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
static int countcommon(String[] A, String[] B, int N, int M)
{
int max_freq[] = new int [ 26 ];
int ans = 0 ;
for ( int i = 0 ; i < M; i++) {
int temp[] = new int [ 26 ];
for ( int j = 0 ; j < B[i].length(); j++) {
temp[B[i].charAt(j) - 'a' ]++;
}
for ( int k = 0 ; k < 26 ; k++) {
max_freq[k] = Math.max(max_freq[k], temp[k]);
}
}
for ( int i = 0 ; i < N; i++) {
int temp[] = new int [ 26 ];
for ( int j = 0 ; j < A[i].length(); j++) {
temp[A[i].charAt(j) - 'a' ]++;
}
boolean check = false ;
for ( int k = 0 ; k < 26 ; k++) {
if (max_freq[k] > temp[k]) {
check = true ;
break ;
}
}
if (!check)
ans++;
}
return ans;
}
public static void main (String[] args) {
String A[] = { "geekolymic" , "google" , "amazon" };
String B[] = { "go" };
int N = A.length;
int M = B.length;
System.out.println(countcommon(A, B, N, M));
}
}
|
Python3
from random import randrange
def countcommon(A, B, N, M):
max_freq = [ 0 for _ in range ( 26 )]
ans = 0
for i in range ( 0 , M):
temp = [ 0 for _ in range ( 26 )]
for j in range ( 0 , len (B[i])):
temp[ ord (B[i][j]) - ord ( 'a' )] + = 1
for k in range ( 0 , 26 ):
max_freq[k] = max (max_freq[k], temp[k])
for i in range ( 0 , N):
temp = [ 0 for _ in range ( 26 )]
for j in range ( 0 , len (A[i])):
temp[ ord (A[i][j]) - ord ( 'a' )] + = 1
f = False
for k in range ( 0 , k):
if (max_freq[k] > temp[k]):
f = True
break
if (f = = False ):
ans + = 1
return ans
if __name__ = = "__main__" :
A = [ "geekolymic" , "google" , "amazon" ]
B = [ "go" ]
N = len (A)
M = len (B)
print (countcommon(A, B, N, M))
|
C#
using System;
public class GFG {
static int countcommon(String[] A, String[] B, int N, int M)
{
int []max_freq = new int [26];
int ans = 0;
for ( int i = 0; i < M; i++) {
int []temp = new int [26];
for ( int j = 0; j < B[i].Length; j++) {
temp[B[i][j] - 'a' ]++;
}
for ( int k = 0; k < 26; k++) {
max_freq[k] = Math.Max(max_freq[k], temp[k]);
}
}
for ( int i = 0; i < N; i++) {
int []temp = new int [26];
for ( int j = 0; j < A[i].Length; j++) {
temp[A[i][j] - 'a' ]++;
}
bool check = false ;
for ( int k = 0; k < 26; k++) {
if (max_freq[k] > temp[k]) {
check = true ;
break ;
}
}
if (!check)
ans++;
}
return ans;
}
public static void Main(String[] args) {
String []A = { "geekolymic" , "google" , "amazon" };
String []B = { "go" };
int N = A.Length;
int M = B.Length;
Console.WriteLine(countcommon(A, B, N, M));
}
}
|
Javascript
<script>
function countcommon(A, B, N, M)
{
let max_freq = new Array(26);
let ans = -1;
for (let i = 0; i < M; i++) {
let temp = new Array(26);
for (let j = 0; j < B[i].length; j++) {
temp[B[i][j] - 'a' ]++;
}
for (let k = 0; k < 26; k++) {
max_freq[k] = Math.max(max_freq[k], temp[k]);
}
}
for (let i = 0; i < N; i++) {
let temp = new Array(26);
for (let j = 0; j < A[i].length; j++) {
temp[A[i][j] - 'a' ]++;
}
let check = false ;
for (let k = 0; k < 26; k++) {
if (max_freq[k] > temp[k]) {
check = true ;
break ;
}
}
if (!check)
ans++;
}
return ans;
}
let A = [ "geekolymic" , "google" , "amazon" ];
let B = [ "go" ];
let N = A.length;
let M = B.length;
document.write(countcommon(A, B, N, M));
</script>
|
Time Complexity: O(max(N, M)*26), where N is the size of A and M is the size of B
Auxiliary Space: O(26)
Another Approach:
- Initialize a frequency array freqB of size 26 (for small case letters) with all elements as 0.
- Traverse the array B[] and for each string, update the frequency array by incrementing the count of characters present in that string.
Initialize a variable count to 0.
Traverse the array A[] and for each string, initialize a frequency array freqA of size 26 with all elements as 0.
- Traverse the current string of A[] and for each character, update the frequency array freqA by incrementing the count of that character.
- Traverse the frequency array freqB and for each non-zero element, check if the corresponding element in freqA is greater than or equal to the frequency in freqB. If not, break from the loop and move to the next string of A[].
- If all the elements in freqB are present in freqA, increment the count variable.
- Return the count variable as the result.
Below is the implementation of the above approach :
C++
#include <bits/stdc++.h>
using namespace std;
int countcommon(vector<string> A, vector<string> B, int N, int M)
{
int freqB[26] = {0};
for ( int i = 0; i < M; i++) {
string curr = B[i];
for ( int j = 0; j < curr.length(); j++) {
freqB[curr[j] - 'a' ]++;
}
}
int count = 0;
for ( int i = 0; i < N; i++) {
int freqA[26] = {0};
string curr = A[i];
for ( int j = 0; j < curr.length(); j++) {
freqA[curr[j] - 'a' ]++;
}
bool flag = true ;
for ( int j = 0; j < 26; j++) {
if (freqB[j] != 0 && freqA[j] < freqB[j]) {
flag = false ;
break ;
}
}
if (flag) {
count++;
}
}
return count;
}
int main()
{
vector<string> A{ "geekolymic" , "google" , "amazon" };
vector<string> B{ "go" };
int N = A.size();
int M = B.size();
cout << countcommon(A, B, N, M) << endl;
return 0;
}
|
Java
import java.util.*;
class Main {
static int countcommon(List<String> A, List<String> B,
int N, int M)
{
int freqB[] = new int [ 26 ];
for ( int i = 0 ; i < M; i++) {
String curr = B.get(i);
for ( int j = 0 ; j < curr.length(); j++) {
freqB[curr.charAt(j) - 'a' ]++;
}
}
int count = 0 ;
for ( int i = 0 ; i < N; i++) {
int freqA[] = new int [ 26 ];
String curr = A.get(i);
for ( int j = 0 ; j < curr.length(); j++) {
freqA[curr.charAt(j) - 'a' ]++;
}
boolean flag = true ;
for ( int j = 0 ; j < 26 ; j++) {
if (freqB[j] != 0 && freqA[j] < freqB[j]) {
flag = false ;
break ;
}
}
if (flag) {
count++;
}
}
return count;
}
public static void main(String[] args)
{
List<String> A
= new ArrayList<String>(Arrays.asList(
"geekolymic" , "google" , "amazon" ));
List<String> B
= new ArrayList<String>(Arrays.asList( "go" ));
int N = A.size();
int M = B.size();
System.out.println(countcommon(A, B, N, M));
}
}
|
Python3
def countcommon(A, B, N, M):
freqB = [ 0 ] * 26
for i in range (M):
curr = B[i]
for j in range ( len (curr)):
freqB[ ord (curr[j]) - ord ( 'a' )] + = 1
count = 0
for i in range (N):
freqA = [ 0 ] * 26
curr = A[i]
for j in range ( len (curr)):
freqA[ ord (curr[j]) - ord ( 'a' )] + = 1
flag = True
for j in range ( 26 ):
if freqB[j] ! = 0 and freqA[j] < freqB[j]:
flag = False
break
if flag:
count + = 1
return count
A = [ "geekolymic" , "google" , "amazon" ]
B = [ "go" ]
N = len (A)
M = len (B)
print (countcommon(A, B, N, M))
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static int CountCommon(List< string > A, List< string > B, int N, int M)
{
int [] freqB = new int [26];
foreach ( string curr in B)
{
foreach ( char c in curr)
{
freqB++;
}
}
int count = 0;
foreach ( string curr in A)
{
int [] freqA = new int [26];
foreach ( char c in curr)
{
freqA++;
}
bool flag = true ;
for ( int j = 0; j < 26; j++)
{
if (freqB[j] != 0 && freqA[j] < freqB[j])
{
flag = false ;
break ;
}
}
if (flag)
{
count++;
}
}
return count;
}
static void Main( string [] args)
{
List< string > A = new List< string > { "geekolymic" , "google" , "amazon" };
List< string > B = new List< string > { "go" };
int N = A.Count;
int M = B.Count;
Console.WriteLine(CountCommon(A, B, N, M));
}
}
|
Javascript
function countcommon(A, B, N, M) {
let freqB = new Array(26).fill(0);
for (let i = 0; i < M; i++) {
let curr = B[i];
for (let j = 0; j < curr.length; j++) {
freqB[curr.charCodeAt(j) - 97]++;
}
}
let count = 0;
for (let i = 0; i < N; i++) {
let freqA = new Array(26).fill(0);
let curr = A[i];
for (let j = 0; j < curr.length; j++) {
freqA[curr.charCodeAt(j) - 97]++;
}
let flag = true ;
for (let j = 0; j < 26; j++) {
if (freqB[j] !== 0 && freqA[j] < freqB[j]) {
flag = false ;
break ;
}
}
if (flag) {
count++;
}
}
return count;
}
let A = [ "geekolymic" , "google" , "amazon" ];
let B = [ "go" ];
let N = A.length;
let M = B.length;
console.log(countcommon(A, B, N, M));
|
Time Complexity: O(N)
Auxiliary Space: O(1)
Share your thoughts in the comments
Please Login to comment...