<p>You are given an array of <code>events</code> where <code>events[i] = [startDay<sub>i</sub>, endDay<sub>i</sub>]</code>. Every event <code>i</code> starts at <code>startDay<sub>i</sub></code><sub> </sub>and ends at <code>endDay<sub>i</sub></code>.</p>

<p>You can attend an event <code>i</code> at any day <code>d</code> where <code>startTime<sub>i</sub> &lt;= d &lt;= endTime<sub>i</sub></code>. You can only attend one event at any time <code>d</code>.</p>

<p>Return <em>the maximum number of events you can attend</em>.</p>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>
<img alt="" src="https://assets.leetcode.com/uploads/2020/02/05/e1.png" style="width: 400px; height: 267px;" />
<pre>
<strong>Input:</strong> events = [[1,2],[2,3],[3,4]]
<strong>Output:</strong> 3
<strong>Explanation:</strong> You can attend all the three events.
One way to attend them all is as shown.
Attend the first event on day 1.
Attend the second event on day 2.
Attend the third event on day 3.
</pre>

<p><strong class="example">Example 2:</strong></p>

<pre>
<strong>Input:</strong> events= [[1,2],[2,3],[3,4],[1,2]]
<strong>Output:</strong> 4
</pre>

<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
	<li><code>1 &lt;= events.length &lt;= 10<sup>5</sup></code></li>
	<li><code>events[i].length == 2</code></li>
	<li><code>1 &lt;= startDay<sub>i</sub> &lt;= endDay<sub>i</sub> &lt;= 10<sup>5</sup></code></li>
</ul>

class Solution:
    def maxEvents(self, events: List[List[int]]) -> int:

        heapq.heapify(events)
        curr_day = events[0][0]
        num_events = 0

        started_events = []

        while events or started_events:

            # sort all events starting today based on their end days
            while events and events[0][0] == curr_day:
                nstart, nend = heapq.heappop(events)
                heapq.heappush(started_events, nend)
            
            # pick the quickest ending event that starts today
            heapq.heappop(started_events)
            num_events += 1
            curr_day += 1 # move to next day

            # remove started events whose end date is now expired
            while started_events and started_events[0] < curr_day:
                heapq.heappop(started_events)
            
            # if we finished all started events then move on to the next start day
            if not started_events and events:
                curr_day = events[0][0]

        return  num_events



        """
        TLE solution
        1. sort by start times (using heap), and pop one by one
        2. Pick an event if its unique for the day
        3. For multiple events starting on same day, pick the one with closest end date.
            4. Put rest of the repeated events back in heap, by incrementing their start + 1 (so they get compared by future events)

        """
        # heapq.heapify(events)

        # idx = 0
        # days = 0

        # while events:
        #     start, end = heapq.heappop(events)
        #     if start > end:
        #         continue
        #     days += 1
            
        #     if events and start == events[0][0]:
                
        #         while events[0][0] == start:
        #             next_start, next_end = heapq.heappop(events)
        #             if next_end < end:
        #                 heapq.heappush(events, [start + 1, next_end])
        #                 start, end = next_start, next_end
        #             else:
        #                 heapq.heappush(events, [next_start + 1, next_end])
        
        # return days
53100