- Choose the invariant that makes a window valid or useful.
- Advance the right boundary and add the new element.
- Move the left boundary only as needed while maintaining the invariant and updating the answer.
Code notes
- 61 lines of Python from the credited upstream file count-k-subsequences-of-a-string-with-maximum-beauty.py.
- The implementation visibly relies on hash lookup.
- No explicit loop blocks detected.
Complexity
Confirm that neither pointer moves backwards; if so, the scan is usually linear apart from the window’s data-structure operations.
Check the problem constraints before deciding whether this complexity will pass.
Use this to learn the idea, then write your own version.
123 4import collections5import random6 7 89class Solution(object):10 def countKSubsequencesWithMaxBeauty(self, s, k):11 """12 :type s: str13 :type k: int14 :rtype: int15 """16 MOD = 10**9+717 fact, inv, inv_fact = [[1]*2 for _ in xrange(3)]18 def nCr(n, k):19 if not (0 <= k <= n):20 return 021 while len(inv) <= n: 22 fact.append(fact[-1]*len(inv) % MOD)23 inv.append(inv[MOD%len(inv)]*(MOD-MODlen(inv)) % MOD) 24 inv_fact.append(inv_fact[-1]*inv[-1] % MOD)25 return (fact[n]*inv_fact[n-k] % MOD) * inv_fact[k] % MOD26 27 def nth_element(nums, n, compare=lambda a, b: a < b):28 def tri_partition(nums, left, right, target, compare):29 mid = left30 while mid <= right:31 if nums[mid] == target:32 mid += 133 elif compare(nums[mid], target):34 nums[left], nums[mid] = nums[mid], nums[left]35 left += 136 mid += 137 else:38 nums[mid], nums[right] = nums[right], nums[mid]39 right -= 140 return left, right41 42 left, right = 0, len(nums)-143 while left <= right:44 pivot_idx = random.randint(left, right)45 pivot_left, pivot_right = tri_partition(nums, left, right, nums[pivot_idx], compare)46 if pivot_left <= n <= pivot_right:47 return48 elif pivot_left > n:49 right = pivot_left-150 else: 51 left = pivot_right+152 53 cnt = collections.Counter(s)54 if len(cnt) < k:55 return 056 freqs = cnt.values()57 nth_element(freqs, k-1, lambda a, b: a > b)58 n = freqs.count(freqs[k-1])59 r = sum(freqs[i] == freqs[k-1] for i in xrange(k))60 return reduce(lambda a, b: a*b%MOD, (freqs[i] for i in xrange(k)), 1)*nCr(n, r)%MOD61