Sliding Window
26 / 170Sliding WindowLesson 5 of 6About 76 min
The hardest window in the set: grow until the window is sufficient, then shrink while keeping it sufficient.
Here is that shape on a simpler requirement than the problem below: the shortest stretch containing at least k distinct characters.
def shortest_with_k_distinct(text, k): counts = {} left = 0 best = len(text) + 1 for right in range(len(text)): counts[text[right]] = counts.get(text[right], 0) + 1 while len(counts) >= k: # still sufficient best = min(best, right - left + 1) leaving = text[left] counts[leaving] -= 1 if counts[leaving] == 0: del counts[leaving] left += 1 return best if best <= len(text) else 0 print(shortest_with_k_distinct("abcba", 3))print(shortest_with_k_distinct("aaa", 2))Write down four things: what the window remembers, what makes it sufficient, where you record, and what you return when nothing works. If all four are on paper before you type, this problem is mechanical. If they are not, it is very hard.
This counts how many characters have met their requirement, but uses the wrong condition. Type what it prints.
def have_count(window_counts, required): have = 0 for ch, count in window_counts.items(): if ch in required and count >= required[ch]: have += 1 return have def buggy_stream(text, required): counts = {} have = 0 for ch in text: counts[ch] = counts.get(ch, 0) + 1 if ch in required and counts[ch] >= required[ch]: have += 1 return have print(have_count({"a": 4, "b": 1}, {"a": 2, "b": 1}))print(buggy_stream("aaaab", {"a": 2, "b": 1}))Build the piece that the problem needs, on its own. make_requirement turns a string into a count map. update_have takes the window counts, the requirement, a character, and the direction it moved (+1 entering or -1 leaving), applies the change, and returns the delta that should be applied to have, which is 1, -1, or 0. is_sufficient reports whether every requirement is met.
Tests
req = make_requirement("aabc")print(req)window = {}print(update_have(window, req, "a", 1), update_have(window, req, "a", 1))print(update_have(window, req, "b", 1), update_have(window, req, "a", 1))print(update_have(window, req, "a", -1))print(update_have(window, req, "a", -1))print(is_sufficient({"a": 2, "b": 1, "c": 1}, req), is_sufficient({"a": 1, "b": 1, "c": 1}, req))Output
Run tests to see output.
Read the constraints first and let them tell you what complexity is expected. Derive the approach, implement it, run the tests, and submit when it passes.