~/problems / Greedy

Where do 1..k sit together?

medium ~20 min Uber

p is a permutation of 1, 2, ..., n (every number from 1 to n exactly once, in some order). For a given k, call p k-compact if some block of k adjacent positions of p holds exactly the numbers 1, 2, ..., k, in any order.

Write compact_levels(p: list[int]) -> str that returns a string of length n whose k-th character (1-based) is '1' if p is k-compact and '0' otherwise.

compact_levels([4, 1, 3, 2, 5])   # "10111"
#   k=1: [1]                 yes
#   k=2: 1 and 2 are at positions 1 and 3, not adjacent       no
#   k=3: [1, 3, 2]           yes
#   k=4: [4, 1, 3, 2]        yes
#   k=5: the whole array     yes
compact_levels([2, 1])            # "11"
compact_levels([1, 3, 2])         # "101"

The last character is always '1'. Constraints: 1 <= n <= 2 * 10**5.

Checking each k by sliding a window or re-scanning positions is O(n²) or worse. Aim for O(n): think about where the numbers 1..k sit, and what changes when you add k + 1.

Topic: Greedy with sorting. Sort, then take the locally best choice; prove it with an exchange argument.

Read the visual guide
0:00
Ctrl ' run · Ctrl ↵ submit
esc