- 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 3049.py.
- The implementation visibly relies on sequence storage, hash lookup, work queue.
- 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.
1class Solution:2 def earliestSecondToMarkIndices(3 self,4 nums: list[int],5 changeIndices: list[int],6 ) -> int:7 8 secondToIndex = self._getSecondToIndex(nums, changeIndices)9 numsSum = sum(nums)10 11 def canMark(maxSecond: int) -> bool:12 """13 Returns True if all indices of `nums` can be marked within `maxSecond`.14 """15 16 17 minHeap = []18 marks = 019 20 for second in range(maxSecond - 1, -1, -1):21 if second in secondToIndex:22 23 index = secondToIndex[second]24 heapq.heappush(minHeap, nums[index])25 if marks == 0:26 27 28 heapq.heappop(minHeap)29 marks += 130 else:31 32 33 marks -= 134 else:35 36 37 marks += 138 39 decrementAndMarkCost = ((numsSum - sum(minHeap)) +40 (len(nums) - len(minHeap)))41 zeroAndMarkCost = len(minHeap) + len(minHeap)42 return decrementAndMarkCost + zeroAndMarkCost <= maxSecond43 44 l = 045 r = len(changeIndices) + 146 ans = bisect.bisect_left(range(l, r), True, key=canMark) + l47 return ans if ans <= len(changeIndices) else -148 49 def _getSecondToIndex(50 self,51 nums: list[int],52 changeIndices: list[int],53 ) -> dict[int, int]:54 55 indexToFirstSecond = {}56 for zeroIndexedSecond, oneIndexedIndex in enumerate(changeIndices):57 index = oneIndexedIndex - 1 58 if nums[index] > 0 and index not in indexToFirstSecond:59 indexToFirstSecond[index] = zeroIndexedSecond60 return {second: index for index, second in indexToFirstSecond.items()}61