子串的最大出现次数
难度:
标签:
题目描述
代码结果
运行时间: 95 ms, 内存: 0.0 MB
/*
* 思路:
* 1. 使用Java Stream来遍历字符串并生成所有可能的子串。
* 2. 对每个子串进行过滤,保留满足条件的子串。
* 3. 使用Collectors.groupingBy和Collectors.counting来统计每个子串的出现次数。
* 4. 返回出现次数最多的子串的次数。
*/
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class SolutionStream {
public int maxFreq(String s, int maxLetters, int minSize, int maxSize) {
Map<String, Long> substringCount = IntStream.range(0, s.length() - minSize + 1)
.mapToObj(i -> s.substring(i, i + minSize))
.filter(sub -> isValid(sub, maxLetters))
.collect(Collectors.groupingBy(sub -> sub, Collectors.counting()));
return substringCount.values().stream().mapToInt(Long::intValue).max().orElse(0);
}
private boolean isValid(String sub, int maxLetters) {
long uniqueCount = sub.chars().distinct().count();
return uniqueCount <= maxLetters;
}
}
解释
方法:
题解的核心思路是先考虑最小子串长度 `minSize`,因为较小的子串更可能在字符串中重复出现。首先,使用一个滑动窗口的方法生成所有长度为 `minSize` 的子串,并利用 `collections.Counter` 统计这些子串的出现频率。随后,遍历这个频率字典,选出那些满足“子串中不同字母的数目不超过 `maxLetters`”的子串,并记录它们的最大出现次数。这种方法避免了考虑 `maxSize`,因为更长的子串出现次数通常不会超过最小长度子串的出现次数。
时间复杂度:
O(n * minSize)
空间复杂度:
O(n)
代码细节讲解
🦆
在题解中提到使用滑动窗口生成所有长度为 `minSize` 的子串,为什么不需要同时考虑 `maxSize` 的子串呢?
▷🦆
题解中使用 `collections.Counter` 统计子串出现频率时,是否考虑了字符串中的重叠子串?如果有,这对结果有何影响?
▷🦆
为什么题解中最终选择返回 `max([count[w] for w in count if len(set(w)) <= maxLetters] + [0])`,而不是直接从计数器中获取最大值?
▷🦆
当 `minSize` 接近于字符串 `s` 的长度时,这种算法的效率如何?是否存在更优化的处理方式?
▷