Leetcode 1170: Compare Strings by Frequency of the Smallest Character
Define a function
f(s)
as the frequency of the lexicographically smallest character in a non-empty string s
. For example, for s = 'abc'
, f(s) = 1
because the smallest character is 'a'
, appearing once. Given an array of strings queries
and another array words
, return an array where each entry corresponds to the number of strings in words
where f(W)
is greater than f(queries[i])
for a given i
.Problem
Approach
Steps
Complexity
Input: The input consists of two arrays of strings: `queries` and `words`.
Example: Input: queries = ["xyz", "aac"], words = ["aaa", "bbc", "cccc"]
Constraints:
• 1 <= queries.length <= 2000
• 1 <= words.length <= 2000
• 1 <= queries[i].length, words[i].length <= 10
• queries[i][j], words[i][j] consist of lowercase English letters.
Output: An array of integers representing the count of strings in `words` such that `f(W) > f(queries[i])` for each query.
Example: Output: [3, 2]
Constraints:
Goal: Calculate `f(s)` for each string in `queries` and `words`, then compare the values to determine counts.
Steps:
• Calculate `f(W)` for all strings in `words` and store the results in a sorted array.
• For each query in `queries`, compute `f(queries[i])`.
• Use binary search on the sorted `words` array to count the number of `f(W)` values greater than `f(queries[i])`.
Goal: Constraints on input sizes and character types are provided.
Steps:
• 1 <= queries.length <= 2000
• 1 <= words.length <= 2000
• 1 <= queries[i].length, words[i].length <= 10
Assumptions:
• All strings are non-empty and contain only lowercase English letters.
• Input: Input: queries = ["abc", "dd"], words = ["a", "bbb", "cccc"]
• Explanation: For query 'abc', `f(abc) = 1`, and the counts of words with higher `f` are 2 (`bbb`, `cccc`). For query 'dd', `f(dd) = 2`, and only `cccc` has a higher `f`.
Approach: Use a frequency counting method combined with sorting and binary search to optimize comparisons.
Observations:
• The calculation of `f(s)` is straightforward by counting character frequencies.
• Sorting `words` by their `f(W)` values allows efficient comparisons using binary search.
• Precomputing and sorting `f(W)` for `words` can save computation during query evaluation.
Steps:
• Compute and store `f(W)` values for all strings in `words`.
• Sort the computed `f(W)` values for efficient comparisons.
• For each string in `queries`, calculate `f(queries[i])`.
• Use binary search to determine the number of `f(W)` values greater than `f(queries[i])`.
Empty Inputs:
• Empty `queries` or `words` arrays are invalid per constraints.
Large Inputs:
• Maximum array sizes for `queries` and `words`.
Special Values:
• All characters in a string are the same.
Constraints:
• Minimal and maximal string lengths in both arrays.
vector<int> numSmallerByFrequency(vector<string>& q, vector<string>& w) {
vector<int> bp(26, 0), ans(w.size(), 0), res(q.size(), 0);
int j = 0;
for(auto s: w) {
bp= vector<int>(26, 0);
for(char x: s) {
bp[x - 'a']++;
}
for(int i = 0; i < 26; i++) {
if(bp[i] > 0) {
ans[j] = bp[i];
break;
}
}
j++;
}
sort(ans.begin(), ans.end());
j = 0;
for(auto s: q) {
bp= vector<int>(26, 0);
for(char x: s) {
bp[x - 'a']++;
}
for(int i = 0; i < 26; i++) {
if(bp[i] > 0) {
res[j] = bp[i];
break;
}
}
j++;
}
// for(auto x: res)
// cout << x << " ";
// cout << "\n";
vector<int> ret(q.size(), 0);
for(int i = 0; i < res.size(); i++) {
int qr = res[i];
auto it = upper_bound(ans.begin(), ans.end(), qr);
ret[i] = ans.end() - it;
// cout << ret[i] << " ";
}
return ret;
}
1 : Function Definition
vector<int> numSmallerByFrequency(vector<string>& q, vector<string>& w) {
Define the function `numSmallerByFrequency` that takes two vectors of strings `q` and `w` as input and returns a vector of integers.
2 : Variable Initialization
vector<int> bp(26, 0), ans(w.size(), 0), res(q.size(), 0);
Initialize three vectors: `bp` to store character frequencies, `ans` to store the smallest frequency from each string in `w`, and `res` to store the smallest frequency from each string in `q`.
3 : Variable Initialization
int j = 0;
Initialize the index `j` to 0 for traversing the `w` vector.
4 : Loop
for(auto s: w) {
Start a loop that iterates through each string `s` in the vector `w`.
5 : Variable Initialization
bp = vector<int>(26, 0);
Reinitialize the `bp` vector to store the frequency of characters in the current string `s`.
6 : Loop
for(char x: s) {
Start a loop to count the occurrences of each character in the string `s`.
7 : Frequency Calculation
bp[x - 'a']++;
Increment the count for the character `x` in the `bp` vector by adjusting it to the appropriate index (`x - 'a'`).
8 : Loop
for(int i = 0; i < 26; i++) {
Start a loop to check each index of the `bp` vector to find the smallest frequency of any character.
9 : Conditional
if(bp[i] > 0) {
Check if the current character has a non-zero frequency.
10 : Assignment
ans[j] = bp[i];
Assign the smallest non-zero frequency found to the corresponding position in the `ans` vector.
11 : Flow Control
break;
Exit the loop once the smallest frequency is assigned.
12 : Index Update
j++;
Increment the index `j` to move to the next string in `w`.
13 : Sorting
sort(ans.begin(), ans.end());
Sort the `ans` vector in ascending order to prepare for comparisons with `q`.
14 : Variable Initialization
j = 0;
Reinitialize `j` to 0 for iterating over the `q` vector.
15 : Loop
for(auto s: q) {
Start a loop that iterates through each string `s` in the vector `q`.
16 : Variable Initialization
bp = vector<int>(26, 0);
Reinitialize the `bp` vector for the current string `s` in `q`.
17 : Loop
for(char x: s) {
Start a loop to count the occurrences of each character in the string `s`.
18 : Frequency Calculation
bp[x - 'a']++;
Increment the count for the character `x` in the `bp` vector by adjusting it to the appropriate index (`x - 'a'`).
19 : Loop
for(int i = 0; i < 26; i++) {
Start a loop to check each index of the `bp` vector to find the smallest frequency of any character.
20 : Conditional
if(bp[i] > 0) {
Check if the current character has a non-zero frequency.
21 : Assignment
res[j] = bp[i];
Assign the smallest non-zero frequency found to the corresponding position in the `res` vector.
22 : Flow Control
break;
Exit the loop once the smallest frequency is assigned.
23 : Index Update
j++;
Increment the index `j` to move to the next string in `q`.
24 : Result Calculation
vector<int> ret(q.size(), 0);
Initialize the result vector `ret` to store the final result for each string in `q`.
25 : Loop
for(int i = 0; i < res.size(); i++) {
Start a loop to calculate the number of strings in `w` that have a smaller smallest character frequency than the corresponding string in `q`.
26 : Binary Search
int qr = res[i];
Store the smallest frequency for the current string in `q`.
27 : Binary Search
auto it = upper_bound(ans.begin(), ans.end(), qr);
Use binary search to find the position in the `ans` vector where `qr` can be inserted to maintain sorted order.
28 : Result Assignment
ret[i] = ans.end() - it;
Assign the count of elements greater than `qr` in `ans` to the result vector `ret`.
29 : Return
return ret;
Return the result vector `ret`.
Best Case: O(n log n + m log n) for n = |words| and m = |queries|.
Average Case: O(n log n + m log n).
Worst Case: O(n log n + m log n).
Description: Precomputing and sorting `words` is O(n log n), and each query is resolved in O(log n).
Best Case: O(n + m).
Worst Case: O(n + m) for storing `f(W)` and results.
Description: Additional space for arrays to store computed values.
LeetCode Solutions Library / DSA Sheets / Course Catalog |
---|
comments powered by Disqus