LeetCode 1170. 比较字符串最小字母出现频次
题目描述
思路分析
解法一:统计最小字符频次 + 二分(推荐)
核心思路:
- 定义
f(s)为字符串中最小字母的出现次数。- 先计算
words的f值并排序。- 对每个
query计算f(query),用二分找出words中f > f(query)的数量。
复杂度分析:
- 时间复杂度:O((m + n) log n + L),其中 n 为
words数量,m 为queries数量,L 为总字符串长度。- 空间复杂度:O(n),存储
words的频次数组。
import java.util.Arrays;
class Solution {
public int[] numSmallerByFrequency(String[] queries, String[] words) {
int[] freqWords = new int[words.length];
for (int i = 0; i < words.length; i++) {
freqWords[i] = minCharFreq(words[i]);
}
Arrays.sort(freqWords);
int[] res = new int[queries.length];
for (int i = 0; i < queries.length; i++) {
int q = minCharFreq(queries[i]);
int idx = upperBound(freqWords, q);
res[i] = freqWords.length - idx;
}
return res;
}
private int minCharFreq(String s) {
char min = 'z';
int count = 0;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c < min) {
min = c;
count = 1;
} else if (c == min) {
count++;
}
}
return count;
}
private int upperBound(int[] arr, int target) {
int left = 0;
int right = arr.length;
while (left < right) {
int mid = left + (right - left) / 2;
if (arr[mid] <= target) {
left = mid + 1;
} else {
right = mid;
}
}
return left;
}
}
import "sort"
func numSmallerByFrequency(queries []string, words []string) []int {
freqWords := make([]int, len(words))
for i, w := range words {
freqWords[i] = minCharFreq(w)
}
sort.Ints(freqWords)
res := make([]int, len(queries))
for i, q := range queries {
fq := minCharFreq(q)
idx := sort.Search(len(freqWords), func(i int) bool {
return freqWords[i] > fq
})
res[i] = len(freqWords) - idx
}
return res
}
func minCharFreq(s string) int {
min := byte('z')
count := 0
for i := 0; i < len(s); i++ {
c := s[i]
if c < min {
min = c
count = 1
} else if c == min {
count++
}
}
return count
}
相似题目
| 题目 | 难度 | 考察点 |
|---|---|---|
| 242. 有效的字母异位词 | 简单 | 频次统计 |
| 451. 根据字符出现频率排序 | 中等 | 频次统计 |
| 692. 前K个高频单词 | 中等 | 频次统计 |
| 387. 字符串中的第一个唯一字符 | 简单 | 频次统计 |
| 1189. “气球” 的最大数量 | 简单 | 频次统计 |
本博客所有文章除特别声明外,均采用
CC BY-NC-SA 4.0
许可协议,转载请注明出处!