Longest Substring with At Most K Distinct Characters

Question

Given a string s, find the length of the longest substring T that contains at most k distinct characters.

Example

For example, Given s = "eceba", k = 3,

T is "eceb" which its length is 4.

Challenge

O(n), n is the size of the string s.

Tags

String Two Pointers LintCode Copyright Hash Table

Related Problems

Medium Longest Substring Without Repeating Characters

Analysis

窗口型two pointers的又一实例。

需要注意的是内层while循环中的跳出条件,是!map.containsKey(ch_j) && map.size() == k,表明在目前出现了第一个character将使得map.size() > k,因此break。跳出内层while循环时,j - i就是substring的长度,因为j指向了substring的下一个char (假设j指向substring的尾部字符,则应该用j - i + 1计算substring长度)。

Solution

Two Pointers

(Preferred Implementation)* Sliding Window - Two Pointers (16ms, 48.48%)

O(n) time, O(n) space

辅助HashMap存sliding window中每个distinct character的出现次数,记录元素在窗口中出现次数;

当HashMap中的元素个数大于k时,就需要移动慢指针,并且每次向前移动慢指针时,就给慢指针对应元素的计数减1,如果减为0,则remove慢指针对应元素。直到HashMap中的元素个数 == k。则继续外层循环,移动快指针,加入新的元素,或者更新原有元素的计数。

Follow Up

The interviewer may say that the string is given as a steam. In this situation, we can't maintain a "left pointer" as the classical O(n) hashmap solution.

[[https://leetcode.com/problems/longest-substring-with-at-most-k-distinct-characters/discuss/80044/Java-O(nlogk)-using-TreeMap-to-keep-last-occurrence-Interview-"follow-up"-question!](https://leetcode.com/problems/longest-substring-with-at-most-k-distinct-characters/discuss/80044/Java-O(nlogk)-using-TreeMap-to-keep-last-occurrence-Interview-"follow-up"-question!](https://leetcode.com/problems/longest-substring-with-at-most-k-distinct-characters/discuss/80044/Java-O%28nlogk%29-using-TreeMap-to-keep-last-occurrence-Interview-"follow-up"-question!]%28https://leetcode.com/problems/longest-substring-with-at-most-k-distinct-characters/discuss/80044/Java-O%28nlogk%29-using-TreeMap-to-keep-last-occurrence-Interview-"follow-up"-question!)\)

Instead of recording each char's count, we keep track of char's last occurrence. If you consider k as constant, it is also a O(n) algorithm.

inWindow keeps track of each char in window and its last occurrence position

TreeMap + HashMap - O(nlogk)

Another Implementation based on LinkedHashMap - O(n)

Last updated

Was this helpful?