Count of strings in the first array which are smaller than every string in the second array

Given two arrays A[] and B[] which consists of N and M strings respectively. A string S1 is said to be smaller than string S2 if the frequency of the smallest character in the S1 is smaller than the frequency of the smallest character in S2. The task is to count the number of strings in A[] which are smaller than B[i] for every i.

Examples:

Input: A[] = {“aaa”, “aa”, “bdc”}, B[] = {“cccch”, “cccd”}
Output: 3 2
“cccch” has frequency of the smallest character as 4, and all the strings
in A[] have frequencies of the smallest characters less than 4.
“cccd” has frequency of the smallest character as 3 and only “aa” and “bdc”
have frequencies of the smallest character less than 3.

Input: A[] = {“abca”, “jji”}, B[] = {“jhgkki”, “aaaa”, “geeks”}
Output: 0 2 1

A naive approach is to take every string in B[] and then count the number of strings in A[] which will satisfy the condition.

An efficient approach is to solve it using Binary Search and some pre-calculations as mentioned below:

  • Initially count the frequency of the smallest character of every string and store in the vector/array.
  • Sort the vector/array in ascending order.
  • Now for every string in B[i], find the frequency of the smallest character.
  • Using lower_bound function in C++, or by doing a binary search in the vector/array, find the count of numbers which has frequency smaller than the frequency of the smallest character for every B[i].

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
#define MAX 26
// Function to count the number of smaller
// strings in A[] for every string in B[]
vector<int> findCount(string a[], string b[], int n, int m)
{
  
    // Count the frequency of all characters
    int freq[MAX] = { 0 };
  
    vector<int> smallestFreq;
  
    // Iterate for all possible strings in A[]
    for (int i = 0; i < n; i++) {
        string s = a[i];
        memset(freq, 0, sizeof freq);
  
        // Increase the frequency of every character
        for (int j = 0; j < s.size(); j++) {
            freq[s[j] - 'a']++;
        }
  
        // Check for the smallest character's frequency
        for (int j = 0; j < MAX; j++) {
  
            // Get the smallest character frequency
            if (freq[j]) {
  
                // Insert it in the vector
                smallestFreq.push_back(freq[j]);
                break;
            }
        }
    }
  
    // Sort the count of all the frequency of the smallest
    // character in every string
    sort(smallestFreq.begin(), smallestFreq.end());
  
    vector<int> ans;
  
    // Iterate for every string in B[]
    for (int i = 0; i < m; i++) {
        string s = b[i];
  
        // Hash set every frequency 0
        memset(freq, 0, sizeof freq);
  
        // Count the frequency of every character
        for (int j = 0; j < s.size(); j++) {
            freq[s[j] - 'a']++;
        }
  
        int frequency = 0;
  
        // Find the frequency of the smallest character
        for (int j = 0; j < MAX; j++) {
            if (freq[j]) {
                frequency = freq[j];
                break;
            }
        }
  
        // Count the number of strings in A[]
        // which has the frequency of the smaller
        // character less than the frequency of the
        // smaller character of the string in B[]
        int ind = lower_bound(smallestFreq.begin(),
                              smallestFreq.end(), frequency)
                  - smallestFreq.begin();
  
        // Store the answer
        ans.push_back(ind);
    }
  
    return ans;
}
  
// Function to print the answer
void printAnswer(string a[], string b[], int n, int m)
{
  
    // Get the answer
    vector<int> ans = findCount(a, b, n, m);
  
    // Print the number of strings
    // for every answer
    for (auto it : ans) {
        cout << it << " ";
    }
}
  
// Driver code
int main()
{
    string A[] = { "aaa", "aa", "bdc" };
    string B[] = { "cccch", "cccd" };
    int n = sizeof(A) / sizeof(A[0]);
    int m = sizeof(B) / sizeof(B[0]);
  
    printAnswer(A, B, n, m);
  
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation of the approach
import java.util.*;
class GFG
{
    static int MAX = 26;
      
    // Function to count the number of smaller
    // strings in A[] for every String in B[]
    static Vector<Integer> findCount(String a[], 
                                     String b[], 
                                     int n, int m)
    {
      
        // Count the frequency of all characters
        int []freq = new int[MAX];
      
        Vector<Integer> smallestFreq = new Vector<Integer>();
      
        // Iterate for all possible strings in A[]
        for (int i = 0; i < n; i++) 
        {
            String s = a[i];
            Arrays.fill(freq, 0);
              
            // Increase the frequency of every character
            for (int j = 0; j < s.length(); j++) 
            {
                freq[s.charAt(j) - 'a']++;
            }
      
            // Check for the smallest character's frequency
            for (int j = 0; j < MAX; j++)
            {
      
                // Get the smallest character frequency
                if (freq[j] > 0
                {
      
                    // Insert it in the vector
                    smallestFreq.add(freq[j]);
                    break;
                }
            }
        }
      
        // Sort the count of all the frequency of
        // the smallest character in every string
        Collections.sort(smallestFreq);
      
        Vector<Integer> ans = new Vector<Integer>();
      
        // Iterate for every String in B[]
        for (int i = 0; i < m; i++) 
        {
            String s = b[i];
      
            // Hash set every frequency 0
            Arrays.fill(freq, 0);
      
            // Count the frequency of every character
            for (int j = 0; j < s.length(); j++) 
            {
                freq[s.charAt(j) - 'a']++;
            }
      
            int frequency = 0;
      
            // Find the frequency of the smallest character
            for (int j = 0; j < MAX; j++)
            {
                if (freq[j] > 0)
                {
                    frequency = freq[j];
                    break;
                }
            }
      
            // Count the number of strings in A[]
            // which has the frequency of the smaller
            // character less than the frequency of the
            // smaller character of the String in B[]
            int [] array = new int[smallestFreq.size()];
            int k = 0;
            for(Integer val:smallestFreq)
            {
                array[k] = val;
                k++;
            }
                  
            int ind = lower_bound(array, 0
                                  smallestFreq.size(), 
                                  frequency);
      
            // Store the answer
            ans.add(ind);
        }
        return ans;
    }
      
    static int lower_bound(int[] a, int low, 
                           int high, int element)
    {
        while(low < high)
        {
            int middle = low + (high - low) / 2;
            if(element > a[middle])
                low = middle + 1;
            else
                high = middle;
        }
        return low;
    
      
    // Function to print the answer
    static void printAnswer(String a[], String b[],
                            int n, int m)
    {
      
        // Get the answer
        Vector<Integer> ans = findCount(a, b, n, m);
      
        // Print the number of strings
        // for every answer
        for (Integer it : ans) 
        {
            System.out.print(it + " ");
        }
    }
      
    // Driver code
    public static void main(String[] args) 
    {
        String A[] = { "aaa", "aa", "bdc" };
        String B[] = { "cccch", "cccd" };
        int n = A.length;
        int m = B.length;
      
        printAnswer(A, B, n, m);
    }
}
  
// This code is contributed by 29AjayKumar

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 implementation of the approach
from bisect import bisect_left as lower_bound
  
MAX = 26
  
# Function to count the number of smaller
# strings in A for every in B
def findCount(a, b, n, m):
  
    # Count the frequency of all characters
    freq=[0 for i in range(MAX)]
  
    smallestFreq=[]
  
    # Iterate for all possible strings in A
    for i in range(n):
        s = a[i]
  
        for i in range(MAX):
            freq[i]=0
  
        # Increase the frequency of every character
        for j in range(len(s)):
            freq[ord(s[j]) - ord('a')]+= 1
  
        # Check for the smallest character's frequency
        for j in range(MAX):
  
            # Get the smallest character frequency
            if (freq[j]):
  
                # Insert it in the vector
                smallestFreq.append(freq[j])
                break
  
  
    # Sort the count of all the frequency of the smallest
    # character in every string
    smallestFreq=sorted(smallestFreq)
  
    ans=[]
  
    # Iterate for every in B
    for i in range(m):
        s = b[i]
  
        # Hash set every frequency 0
        for i in range(MAX):
            freq[i]=0
  
        # Count the frequency of every character
        for j in range(len(s)):
            freq[ord(s[j]) - ord('a')]+= 1
  
  
        frequency = 0
  
        # Find the frequency of the smallest character
        for j in range(MAX):
            if (freq[j]):
                frequency = freq[j]
                break
  
        # Count the number of strings in A
        # which has the frequency of the smaller
        # character less than the frequency of the
        # smaller character of the in B
        ind = lower_bound(smallestFreq,frequency)
  
        # Store the answer
        ans.append(ind)
  
    return ans
  
  
# Function to prthe answer
def printAnswer(a, b, n, m):
  
    # Get the answer
    ans = findCount(a, b, n, m)
  
    # Prthe number of strings
    # for every answer
    for it in ans:
        print(it,end=" ")
  
# Driver code
  
A = ["aaa", "aa", "bdc"]
B = ["cccch", "cccd"]
n = len(A)
m = len(B)
  
printAnswer(A, B, n, m)
  
# This code is contributed by mohit kumar 29

chevron_right


C#

// C# implementation of the approach
using System;
using System.Collections.Generic;
public class GFG
{
static int MAX = 26;

// Function to count the number of smaller
// strings in A[] for every String in B[]
static List findCount(String []a,
String []b,
int n, int m)
{

// Count the frequency of all characters
int []freq = new int[MAX];

List smallestFreq = new List();

// Iterate for all possible strings in A[]
for (int i = 0; i < n; i++) { String s = a[i]; for (int l = 0; l < freq.Length; l++) freq[l]=0; // Increase the frequency of every character for (int j = 0; j < s.Length; j++) { freq[s[j] - 'a']++; } // Check for the smallest character's frequency for (int j = 0; j < MAX; j++) { // Get the smallest character frequency if (freq[j] > 0)
{

// Insert it in the vector
smallestFreq.Add(freq[j]);
break;
}
}
}

// Sort the count of all the frequency of
// the smallest character in every string
smallestFreq.Sort();

List ans = new List();

// Iterate for every String in B[]
for (int i = 0; i < m; i++) { String s = b[i]; // Hash set every frequency 0 for (int l = 0; l < freq.Length; l++) freq[l]=0; // Count the frequency of every character for (int j = 0; j < s.Length; j++) { freq[s[j] - 'a']++; } int frequency = 0; // Find the frequency of the smallest character for (int j = 0; j < MAX; j++) { if (freq[j] > 0)
{
frequency = freq[j];
break;
}
}

// Count the number of strings in A[]
// which has the frequency of the smaller
// character less than the frequency of the
// smaller character of the String in B[]
int [] array = new int[smallestFreq.Count];
int k = 0;
foreach (int val in smallestFreq)
{
array[k] = val;
k++;
}

int ind = lower_bound(array, 0,
smallestFreq.Count,
frequency);

// Store the answer
ans.Add(ind);
}
return ans;
}

static int lower_bound(int[] a, int low,
int high, int element)
{
while(low < high) { int middle = low + (high - low) / 2; if(element > a[middle])
low = middle + 1;
else
high = middle;
}
return low;
}

// Function to print the answer
static void printAnswer(String []a, String []b,
int n, int m)
{

// Get the answer
List ans = findCount(a, b, n, m);

// Print the number of strings
// for every answer
foreach (int it in ans)
{
Console.Write(it + ” “);
}
}

// Driver code
public static void Main(String[] args)
{
String []A = { “aaa”, “aa”, “bdc” };
String []B = { “cccch”, “cccd” };
int n = A.Length;
int m = B.Length;

printAnswer(A, B, n, m);
}
}
// This code is contributed by Princi Singh

Output:

3 2


My Personal Notes arrow_drop_up

Striver(underscore)79 at Codechef and codeforces D

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.