Frequency of smallest character in first sentence less than that of second sentence
Last Updated :
14 Oct, 2023
Given two array of strings, arr1[] and arr2[], the task is to count the number of strings in arr2[] whose frequency of the smallest characters is less than the frequency of the smallest character for each string in arr1[].
Examples:
Input: arr1[] = {“cbd”}, arr2[] = {“zaaaz”}
Output: 1
Explanation:
The frequency of the smallest characters in “cbd” is 1 which is less than the frequency of the smallest characters in “zaaaz” which is 2.
Therefore, the total count is 1 for the string “cbd”.
Input: arr1[] = {“yyy”,”zz”}, arr2[] = {“x”,”xx”,”xxx”,”xxxx”}
Output: 1 2
Explanation:
1. The frequency of the smallest characters in “yyy” is 3 which is less than the frequency of the smallest characters in “xxxx” which is 4.
Therefore, the total count is 1 for the string “yyy”.
2. The frequency of the smallest characters in “zz” is 2 which is less than the frequency of the smallest characters in “xxx” and “xxxx” which is 3 and 4 respectively.
Therefore, the total count is 2 for the string “zz”.
Approach: This problem can be solved using Greedy Approach. Below are the steps:
- For each string in the array, arr2[] count the frequency of the smallest characters and store it in the array (say freq[]).
- Sort the frequency array freq[].
- Now, for each string in the array arr1[] count the frequency of smallest characters in the string (say X).
- For each X, find the number of elements greater than X in freq[] using Binary Search by using the approach discussed this article.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int countMinFreq(string s)
{
sort(s.begin(), s.end());
return count(s.begin(), s.end(), s[0]);
}
void countLessThan(vector<string>& arr1,
vector<string>& arr2)
{
vector< int > freq;
for (string s : arr2) {
int f = countMinFreq(s);
freq.push_back(f);
}
sort(freq.begin(), freq.end());
for (string s : arr1) {
int f = countMinFreq(s);
auto it = upper_bound(freq.begin(),
freq.end(), f);
int cnt = freq.size()
- (it - freq.begin());
cout << cnt << ' ' ;
}
}
int main()
{
vector<string> arr1, arr2;
arr1 = { "yyy" , "zz" };
arr2 = { "x" , "xx" , "xxx" , "xxxx" };
countLessThan(arr1, arr2);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG
{
static int countMinFreq(String s)
{
char [] tempArray = s.toCharArray();
Arrays.sort(tempArray);
s = new String(tempArray);
int x = 0 ;
for ( int i = 0 ; i < s.length(); i++)
if (s.charAt(i) == s.charAt( 0 ))
x++;
return x;
}
static void countLessThan(List<String> arr1,
List<String> arr2)
{
List<Integer> freq = new ArrayList<Integer>();
for (String s : arr2)
{
int f = countMinFreq(s);
freq.add(f);
}
Collections.sort(freq);
for (String s : arr1) {
int f = countMinFreq(s);
int it = upper_bound(freq, f);
int cnt = freq.size() - it;
System.out.print(cnt + " " );
}
}
static int upper_bound(List<Integer> freq, int f)
{
int low = 0 , high = freq.size() - 1 ;
while (low < high) {
int mid = (low + high) / 2 ;
if (freq.get(mid) > f)
high = mid;
else
low = mid + 1 ;
}
return (freq.get(low) < f) ? low++ : low;
}
public static void main(String[] args)
{
List<String> arr1, arr2;
arr1 = Arrays.asList( new String[] { "yyy" , "zz" });
arr2 = Arrays.asList(
new String[] { "x" , "xx" , "xxx" , "xxxx" });
countLessThan(arr1, arr2);
}
}
|
Python3
from bisect import bisect_right as upper_bound
def countMinFreq(s):
s = sorted (s)
x = 0
for i in s:
if i = = s[ 0 ]:
x + = 1
return x
def countLessThan(arr1, arr2):
freq = []
for s in arr2:
f = countMinFreq(s)
freq.append(f)
feq = sorted (freq)
for s in arr1:
f = countMinFreq(s);
it = upper_bound(freq,f)
cnt = len (freq) - it
print (cnt, end = " " )
if __name__ = = '__main__' :
arr1 = [ "yyy" , "zz" ]
arr2 = [ "x" , "xx" , "xxx" , "xxxx" ]
countLessThan(arr1, arr2);
|
C#
using System;
using System.Collections.Generic;
class GFG {
static int countMinFreq(String s)
{
char [] tempArray = s.ToCharArray();
Array.Sort(tempArray);
s = new string (tempArray);
int x = 0;
for ( int i = 0; i < s.Length; i++)
if (s[i] == s[0])
x++;
return x;
}
static void countLessThan(List< string > arr1,
List< string > arr2)
{
List< int > freq = new List< int >();
foreach ( string s in arr2)
{
int f = countMinFreq(s);
freq.Add(f);
}
freq.Sort();
foreach ( string s in arr1)
{
int f = countMinFreq(s);
int it = upper_bound(freq, f);
int cnt = freq.Count - it;
Console.Write(cnt + " " );
}
}
static int upper_bound(List< int > freq, int f)
{
int low = 0, high = freq.Count - 1;
while (low < high) {
int mid = (low + high) / 2;
if (freq[mid] > f)
high = mid;
else
low = mid + 1;
}
return (freq[low] < f) ? low++ : low;
}
public static void Main( string [] args)
{
List< string > arr1 = new List< string >();
List< string > arr2 = new List< string >();
arr1.Add( "yyy" );
arr1.Add( "zz" );
arr2.Add( "x" );
arr2.Add( "xx" );
arr2.Add( "xxx" );
arr2.Add( "xxxx" );
countLessThan(arr1, arr2);
}
}
|
Javascript
<script>
function upper_bound(freq, f)
{
let low = 0, high = freq.length - 1;
while (low < high) {
let mid = Math.floor((low + high) / 2);
if (freq[mid] > f)
high = mid;
else
low = mid + 1;
}
return (freq[low] < f) ? low++ : low;
}
function countMinFreq(s)
{
s = s.split( '' ).sort().join( '' );
let x = 0;
for (let i=0;i<s.length;i++){
if (s[i] == s[0])
x += 1;
}
return x;
}
function countLessThan(arr1,arr2)
{
let freq = [];
for (let i = 0;i< arr2.length;i++) {
let f = countMinFreq(arr2[i]);
freq.push(f);
}
freq= freq.sort( function (a,b){ return a-b});
for (let i = 0;i< arr1.length;i++) {
let f = countMinFreq(arr1[i]);
let it = upper_bound(freq, f);
let cnt = freq.length
- (it);
document.write(cnt, ' ' );
}
}
let arr1, arr2;
arr1 = [ "yyy" , "zz" ];
arr2 = [ "x" , "xx" , "xxx" , "xxxx" ];
countLessThan(arr1, arr2);
</script>
|
Time Complexity: O(N + M*log M), where N and M are the lengths of given arrays respectively.
Auxiliary Space: O(M)
Efficient Approach:
In this approach, we will use the concept of count sort, to avoid sorting the array. Below are the steps:
- Create a utility function, which calculates the frequency of the smallest character in the string i.e. getF(s).
- Initialize a freq array, of MAX_CHAR + 1, size. This array stores the count of the frequency of the smallest character in the string. For example, if two strings in words array, have smallest character count equals 5, then, freq[5] = 2.
- Now, calculate the cummulative frequency for the freq array. This is done because for query[i], we need to tell the number of strings in the words array, that has smallest character count greater than the smallest character count of query[i].
- At last, traverse the queries array, and freq[getF(queries[i]) + 1], will be the answer for each query.
C++
#include <bits/stdc++.h>
using namespace std;
const int MAX_CHAR = 11;
int getF(string &s)
{
return count(s.begin(), s.end(), *min_element(s.begin(), s.end()));
}
void numSmallerByFrequency(vector<string>& queries, vector<string>& words) {
vector< int > freq(MAX_CHAR + 1, 0);
for ( int i = 0; i < words.size(); i++){
int currFreq = getF(words[i]);
freq[currFreq]++;
}
for ( int i = MAX_CHAR - 2; i >= 0; i--){
freq[i] = freq[i] + freq[i+1];
}
for ( int i = 0; i < queries.size(); i++){
int currFreq = getF(queries[i]);
cout << freq[currFreq + 1] << " " ;
}
}
int main()
{
vector<string> arr1, arr2;
arr1 = { "yyy" , "zz" };
arr2 = { "x" , "xx" , "xxx" , "xxxx" };
numSmallerByFrequency(arr1, arr2);
return 0;
}
|
Java
import java.util.*;
class Main {
public static int getF(String s) {
int minCharCount = Collections.frequency(Arrays.asList(
s.split( "" )),
Collections.min(Arrays.asList(s.split( "" ))));
return minCharCount;
}
public static void numSmallerByFrequency(List<String> queries, List<String> words) {
int MAX_CHAR = 11 ;
int [] freq = new int [MAX_CHAR + 1 ];
for (String word : words) {
int currFreq = getF(word);
freq[currFreq]++;
}
for ( int i = MAX_CHAR - 2 ; i >= 0 ; i--) {
freq[i] = freq[i] + freq[i + 1 ];
}
for (String query : queries) {
int currFreq = getF(query);
System.out.print(freq[currFreq + 1 ] + " " );
}
}
public static void main(String[] args) {
List<String> arr1 = new ArrayList<>(Arrays.asList( "yyy" , "zz" ));
List<String> arr2 = new ArrayList<>(Arrays.asList( "x" , "xx" , "xxx" , "xxxx" ));
numSmallerByFrequency(arr1, arr2);
}
}
|
Python3
def getF(s):
return s.count( min (s, key = s.count))
def num_smaller_by_frequency(queries, words):
MAX_CHAR = 11
freq = [ 0 ] * (MAX_CHAR + 1 )
for word in words:
curr_freq = getF(word)
freq[curr_freq] + = 1
for i in range (MAX_CHAR - 2 , - 1 , - 1 ):
freq[i] = freq[i] + freq[i + 1 ]
for query in queries:
curr_freq = getF(query)
print (freq[curr_freq + 1 ], end = " " )
if __name__ = = "__main__" :
arr1 = [ "yyy" , "zz" ]
arr2 = [ "x" , "xx" , "xxx" , "xxxx" ]
num_smaller_by_frequency(arr1, arr2)
|
C#
using System;
using System.Collections.Generic;
using System.Linq;
class GFG {
const int MAX_CHAR = 11;
static int GetF( string s)
{
return s.Count(c => c == s.Min());
}
static void NumSmallerByFrequency(List< string > queries,
List< string > words)
{
int [] freq = new int [MAX_CHAR + 1];
foreach ( string word in words)
{
int currFreq = GetF(word);
freq[currFreq]++;
}
for ( int i = MAX_CHAR - 2; i >= 0; i--) {
freq[i] = freq[i] + freq[i + 1];
}
foreach ( string query in queries)
{
int currFreq = GetF(query);
Console.Write(freq[currFreq + 1] + " " );
}
}
public static void Main( string [] args)
{
List< string > arr1, arr2;
arr1 = new List< string >{ "yyy" , "zz" };
arr2 = new List< string >{ "x" , "xx" , "xxx" , "xxxx" };
NumSmallerByFrequency(arr1, arr2);
}
}
|
Javascript
function getF(s) {
let minChar = Math.min(...s.split( '' ).map(c => c.charCodeAt()));
return s.split( '' ).filter(c => c.charCodeAt() === minChar).length;
}
function numSmallerByFrequency(queries, words) {
let freq = new Array(MAX_CHAR + 1).fill(0);
words.forEach(word => {
let currFreq = getF(word);
freq[currFreq]++;
});
for (let i = MAX_CHAR - 2; i >= 0; i--) {
freq[i] = freq[i] + freq[i + 1];
}
queries.forEach(query => {
let currFreq = getF(query);
console.log(freq[currFreq + 1] + ' ' );
});
}
const MAX_CHAR = 11;
let arr1 = [ "yyy" , "zz" ];
let arr2 = [ "x" , "xx" , "xxx" , "xxxx" ];
numSmallerByFrequency(arr1, arr2);
|
Time Complexity: O(N + M), where N and M are the lengths of given arrays respectively.
Auxiliary Space: O(maximum number of characters in words and queries array)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...