Java 90% O(n)/O(n) Easy to understand solution using sliding window of fixed size
Intuition\n*Please upvote if you found this solution helpful. \n\nWe want to count the number of valid substrings between minSize and maxSize. A key insight is 
# Intuition\n*Please upvote if you found this solution helpful. \n\nWe want to count the number of valid substrings between minSize and maxSize. A key insight is that if a substring is of size N, at least as many substrings of size N-1 must be in the string. Therefore, we only need to test substrings of length minSize. \n\n# Approach\nSliding window: define a window length of minSize. Capture each substring within the window as we move through the string from left to right. Count the frequency of each substring and store it in a hashmap. \n\nOnce we have traversed the string, we will have a hashmap consisting of all the substrings of size minSize. We check each to see whether each candidate substring is valid (so long as it is longer than the current valid max length substring), by checking whether it consists of <= maxLetters.\n\n# Complexity\n- Time complexity:\n$$O(n)$$ (The length (N) of the string + the number of valid substrings V * the length of each valid substring VL)  O(n + V * VL)\nAt most, if each character in string S is a valid substring, we will iterate through the entire string twice, giving us a time complexity of O(2n) = O(n)\n\n- Space complexity:\n$$O(n)$$ the size of the hashmap\n\n# Code\n```\nclass Solution {\n    public int maxFreq(String s, int maxLetters, int minSize, int maxSize) {\n        HashMap<String, Integer> map = new HashMap<>(); \n        int maxOccurrences = 0; \n\n        int left = 0, right = minSize; //window size \n\n        while (right <= s.length()){\n            //count substrings within a window of size minsize\n            //all substrings larger than minsize must contain substrings of length equal to minsize, \n            //so there will be at least as many unique substrings of length minsize as any longer length\n            String substr = s.substring(left, right); \n            map.put(substr, map.getOrDefault(substr, 0) + 1); \n            left++; right++; //shift window right\n        }\n\n           for (String substr : map.keySet()){    \n            int count = map.get(substr); \n\n            if (count > maxOccurrences && isValidSubstring(substr, maxLetters))\n                maxOccurrences = count;\n        }\n\n        return maxOccurrences;\n    }\n\n    public boolean isValidSubstring(String substr, int maxLetters){\n        HashSet<Character> counts = new HashSet<>(); \n        for (int i = 0; i < substr.length(); i++){\n            char c = substr.charAt(i);\n            counts.add(c);\n        }\n\n        return counts.size() <= maxLetters;\n    }\n}\n```
['Java']