题目描述:
给你一个字符串s ,请你返回满足以下条件且出现次数最大的任意子串的出现次数:
子串中不同字母的数目必须小于等于 maxLetters 。
子串的长度必须大于等于 minSize 且小于等于 maxSize
提示:
1 <= s.length <= 10^5
1 <= maxLetters <= 26
1 <= minSize <= maxSize <= min(26, s.length)
s 只包含小写英文字母。
分析:
分析题目要求,首先题目要求的是任意子串的最大出现次数,子串就代表是截取的连续的一串字符。然后要求这个子串中不同字母的个数最多为maxLetters,长度也有限制,但实际上,maxSize是一个没有用的条件,因为如果一个长度为maxSize的串是出现次数最多的子串,那么它必然包含长度更小的子串与其出现的次数相同,所以可以不考虑这一条件。我的解法是使用哈希表,以字符串类型作为键,该字符串出现的次数作为值,然后从头开始以此遍历minsize长度的子串,进行统计,其中字母数量大于maxLetters的是不存储的。具体的代码如下:
public int maxFreq(String s, int maxLetters, int minSize, int maxSize) { if (s.length()<minSize) return 0; if (s.length()==1&&minSize==1) return 1; StringBuilder stringBuilder = new StringBuilder(s); HashMap<String, Integer> map = new HashMap<>(); HashSet<Character> set = new HashSet<>(); for (int i = 0;i + minSize <= stringBuilder.length();i++){ String temp = stringBuilder.substring(i,i+minSize); for (char c : temp.toCharArray()) { set.add(c); } if (set.size() <= maxLetters){ if (map.get(temp)==null) map.put(temp,1); else { int count = map.get(temp) + 1; map.put(temp,count); } } set.clear(); } int max = 0; for (String s1 : map.keySet()) { max = max>map.get(s1)?max:map.get(s1); } return max; }
我的解法运行时间和内存消耗都是中规中矩的,时间复杂度为O(n*m),n为字符串长度,m为minsize。