- 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
- 63 lines of Python from the credited upstream file count-good-subarrays.py.
- The implementation visibly relies on sequence storage.
- 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 45class Solution(object):6 def countGoodSubarrays(self, nums):7 """8 :type nums: List[int]9 :rtype: int10 """11 def is_proper_subset(a, b):12 return a != b and a|b == b13 14 def is_subset(a, b):15 return a|b == b16 17 right = [len(nums)]*len(nums)18 stk = []19 for i in reversed(xrange(len(nums))):20 while stk and is_subset(nums[stk[-1]], nums[i]):21 stk.pop()22 right[i] = stk[-1] if stk else len(nums)23 stk.append(i)24 result, left = 0, -125 stk = []26 for i in xrange(len(nums)):27 while stk and is_proper_subset(nums[stk[-1]], nums[i]):28 stk.pop()29 left = stk[-1] if stk else -130 stk.append(i)31 result += (i-left)*(right[i]-i)32 return result33 34 35363738class Solution2(object):39 def countGoodSubarrays(self, nums):40 """41 :type nums: List[int]42 :rtype: int43 """44 def is_proper_subset(a, b):45 return a != b and a|b == b46 47 def is_subset(a, b):48 return a|b == b49 50 left = [-1]*len(nums)51 stk = []52 for i in reversed(xrange(len(nums))):53 while stk and not is_proper_subset(nums[i], nums[stk[-1]]):54 left[stk.pop()] = i55 stk.append(i)56 right = [len(nums)]*len(nums)57 stk = []58 for i in xrange(len(nums)):59 while stk and not is_subset(nums[i], nums[stk[-1]]):60 right[stk.pop()] = i61 stk.append(i)62 return sum((i-left[i])*(right[i]-i) for i in xrange(len(nums)))63