class Solution:
def scheduleCourse(self, courses: List[List[int]]) -> int:
""" tc O(NlgN) sc O(N)
main idea: greedy
1. sort by ddl then push duration into heap (note, in negtive value)
2. start from t=0, if t +current_duration <= ddl, push into hp
3. if hp[0] > current_duration, pop out bigger duration, update t
4. class to ake is size of queue
"""
courses.sort(key=lambda x: x[1])
q = []
t = 0
for c in courses:
if t + c[0] <= c[1]:
# add duration time into q
heapq.heappush(q,-c[0])
t += c[0]
# If it exceeds deadline, I can swap current course with current courses that has biggest duration.
elif q and -q[0] > c[0]:
t += c[0] + heapq.heappop(q)
heapq.heappush(q,-c[0])
return len(q)