单词子集
难度:
标签:
题目描述
代码结果
运行时间: 120 ms, 内存: 19.4 MB
/*
* 思路:
* 1. 通过流计算 words2 中每个字母的最大频率。
* 2. 使用流过滤和收集 words1 中满足条件的单词。
*/
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
public class SolutionStream {
public List<String> wordSubsets(String[] words1, String[] words2) {
int[] maxFreq = Arrays.stream(words2)
.map(this::countFreq)
.reduce(new int[26], (acc, bFreq) -> {
for (int i = 0; i < 26; i++) {
acc[i] = Math.max(acc[i], bFreq[i]);
}
return acc;
});
return Arrays.stream(words1)
.filter(a -> isUniversal(countFreq(a), maxFreq))
.collect(Collectors.toList());
}
private int[] countFreq(String s) {
return s.chars().map(c -> c - 'a').collect(() -> new int[26], (arr, c) -> arr[c]++, (arr1, arr2) -> {
for (int i = 0; i < 26; i++) {
arr1[i] += arr2[i];
}
});
}
private boolean isUniversal(int[] aFreq, int[] maxFreq) {
return IntStream.range(0, 26).allMatch(i -> aFreq[i] >= maxFreq[i]);
}
}
解释
方法:
首先,将 words2 中的单词集合化,以去除重复的单词。接着,创建一个函数 jlzd 来计算 words2 中所有单词的最大字母频率需求。这个字典 d 将存储每个字符的最大出现次数,这是通过遍历 words2 的每个单词并更新每个字符的出现次数来实现的。然后,遍历 words1 中的每个单词,检查它是否包含字典 d 中所有字母的最小需求次数。如果某个单词满足所有条件,则认为它是通用单词,并将其添加到结果列表中。
时间复杂度:
O(B*L + A*M)
空间复杂度:
O(C + A)
代码细节讲解
🦆
为什么在处理`words2`时选择去除重复单词而不是直接统计所有单词的字符频率?
▷🦆
在函数`jlzd`中,为每个字符计算最大频率时,为什么选择在每次遇到字符时重新计算其出现次数而不是先统计每个单词的字符频率再进行比较?
▷🦆
解决方案中有没有考虑到`words1`和`words2`为空的情况?如果没有,应该如何处理这些特殊情况?
▷🦆
在遍历`words1`中的单词时,如果一个单词不满足条件,立即使用`break`跳出循环。这种策略对算法性能有何影响?能否进一步优化?
▷