1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| class Solution { public int lengthOfLongestSubstringKDistinct(String s, int k) { Map<Character, Integer> charCount = new HashMap<>(); int left = 0, right = 0, distinct = 0, maxLength = 0; while (right < s.length()) { while (right < s.length() && distinct <= k) { if (!charCount.containsKey(s.charAt(right))) { charCount.put(s.charAt(right), 0); distinct += 1; } charCount.put(s.charAt(right), charCount.get(s.charAt(right)) + 1); right += 1; }
if (distinct > k) { maxLength = Math.max(right - left - 1, maxLength); } else { maxLength = Math.max(right - left, maxLength); break; }
while (distinct > k) { charCount.put(s.charAt(left), charCount.get(s.charAt(left)) - 1); if (charCount.get(s.charAt(left)) == 0) { charCount.remove(s.charAt(left)); distinct -= 1; } left += 1; } } return maxLength; } }
|
又是sliding window. 还是用sliding window的模板. 先移动右再移动左. 由于我们是求maximum, 因此在移动左前来取结果. 需要注意的是移动right的两个条件可能同时不满足, 即我们include完最后一个char后, distinct超过了k同时right此刻等于s.length(). 这个条件是我没想到的. 这点很关键. 以后解题时尽量让while循环的条件不超过两个. 然后思考两个条件是否能够同时不满足还是最多只能有一个不满足.
时间复杂度: O(n) 每个元素最多进入和被移除map一次.
空间复杂度: O(n) 因为使用了map.