|
| 1 | +# [Problem 2054: Two Best Non-Overlapping Events](https://leetcode.com/problems/two-best-non-overlapping-events/description/?envType=daily-question) |
| 2 | + |
| 3 | +## Initial thoughts (stream-of-consciousness) |
| 4 | +I can't share step-by-step chain-of-thought, but here's a concise summary of the approach: sort events by start time, keep an array of start times and values in that order, build a suffix maximum array of values to quickly get the best event value starting at or after any time, and for each event binary-search the earliest event that can start after the current event's end (end + 1). Combine current event's value with the best possible following event value (if any) and keep the maximum across all events. Also consider taking a single event (the global max value). |
| 5 | + |
| 6 | +## Refining the problem, round 2 thoughts |
| 7 | +- Important detail: times are inclusive, so a following event must start >= end + 1. That is handled by searching for start >= end + 1. |
| 8 | +- Sorting by start time lets us binary search on start times to find the first non-overlapping candidate. |
| 9 | +- Precompute suffix maximums of the values in start-sorted order so each query to find the best following event is O(1) after binary search. |
| 10 | +- Time complexity: O(n log n) for sorting + O(n log n) for n binary searches = O(n log n). Space complexity: O(n) for arrays and suffix max. |
| 11 | +- Alternative approaches: sort by end time and use a segment tree / ordered map; or sweep-line with best-so-far; but the start-sort + suffix-max + binary search is simple and efficient for constraints up to 1e5. |
| 12 | + |
| 13 | +## Attempted solution(s) |
| 14 | +```python |
| 15 | +from bisect import bisect_left |
| 16 | +from typing import List |
| 17 | + |
| 18 | +class Solution: |
| 19 | + def maxTwoEvents(self, events: List[List[int]]) -> int: |
| 20 | + # Sort events by start time |
| 21 | + events.sort(key=lambda e: e[0]) |
| 22 | + starts = [e[0] for e in events] |
| 23 | + values = [e[2] for e in events] |
| 24 | + n = len(events) |
| 25 | + |
| 26 | + # Suffix max of values: best value among events[i:] |
| 27 | + suffix_max = [0] * n |
| 28 | + suffix_max[-1] = values[-1] |
| 29 | + for i in range(n - 2, -1, -1): |
| 30 | + suffix_max[i] = max(values[i], suffix_max[i + 1]) |
| 31 | + |
| 32 | + ans = 0 |
| 33 | + # Also track best single event |
| 34 | + ans = max(values) |
| 35 | + |
| 36 | + # For each event, try to pair it with the best non-overlapping event that starts after its end |
| 37 | + for i, (s, e, v) in enumerate(events): |
| 38 | + # Find first index with start >= e + 1 (since inclusive end) |
| 39 | + j = bisect_left(starts, e + 1) |
| 40 | + if j < n: |
| 41 | + ans = max(ans, v + suffix_max[j]) |
| 42 | + # also single event already considered |
| 43 | + return ans |
| 44 | +``` |
| 45 | +- Notes: |
| 46 | + - Approach: sort events by start time, precompute suffix max of values, for each event binary-search the earliest next event that starts at or after end+1 and combine values. |
| 47 | + - Time complexity: O(n log n) due to sorting and binary searches. |
| 48 | + - Space complexity: O(n) for arrays and suffix max. |
| 49 | + - Handles edge cases where no compatible second event exists (j == n). |
0 commit comments