Kotlin: O(n) time and O(n) space with sliding window
\n    fun maxFreq(s: String, maxLetters: Int, minSize: Int, maxSize: Int): Int {\n        val freq = HashMap()\n        val cnt = HashMap()\n        var l = 0; 
\n    fun maxFreq(s: String, maxLetters: Int, minSize: Int, maxSize: Int): Int {\n        val freq = HashMap<Char, Int>()\n        val cnt = HashMap<String, Int>()\n        var l = 0; var res = 0\n        for (r in 0..s.length - 1) {\n            val c = s[r]\n            freq[c] = freq.getOrDefault(c, 0) + 1\n            while (freq.size > maxLetters || r - l + 1 > minSize) {\n                val c = s[l++]\n                freq[c] = freq[c]!! - 1\n                if (freq[c]!! == 0) freq.remove(c)\n            }\n            if (r - l + 1 >= minSize) {\n                val c = s.substring(l..r)\n                cnt[c] = cnt.getOrDefault(c, 0) + 1\n                res = maxOf(res, cnt[c]!!)\n            }\n        }\n        return res\n    }
[]