You are given a 0-indexed 2D integer array of events
where events[i] = [startTimei, endTimei, valuei]
. The ith
event starts at startTimei
and ends at endTimei
, and if you attend this event, you will receive a value of valuei
. You can choose at most two non-overlapping events to attend such that the sum of their values is maximized.
Return this maximum sum.
Note that the start time and end time is inclusive: that is, you cannot attend two events where one of them starts and the other ends at the same time. More specifically, if you attend an event with end time t
, the next event must start at or after t + 1
.
Example 1:
Input: events = [[1,3,2],[4,5,2],[2,4,3]] Output: 4 Explanation: Choose the green events, 0 and 1 for a sum of 2 + 2 = 4.
Example 2:
Input: events = [[1,3,2],[4,5,2],[1,5,5]] Output: 5 Explanation: Choose event 2 for a sum of 5.
Example 3:
Input: events = [[1,5,3],[1,5,1],[6,6,5]] Output: 8 Explanation: Choose events 0 and 2 for a sum of 3 + 5 = 8
Constraints:
2 <= events.length <= 105
events[i].length == 3
1 <= startTimei <= endTimei <= 109
1 <= valuei <= 106
题目链接:https://leetcode.com/problems/two-best-non-overlapping-events/
题目大意:最多选两个不相交的区间,求其value和的最大值
题目分析:对左端点排序,预处理每段区间到最右的最大value值,枚举左端点,二分右端点即可
40ms,时间击败81.8%
class Solution {
class Event implements Comparable {
int st, ed, val;
Event(int st, int ed, int val) {
this.st = st;
this.ed = ed;
this.val = val;
}
@Override
public int compareTo(Object o) {
Event e = (Event) o;
if (this.st > e.st) {
return 1;
} else if (this.st < e.st) {
return -1;
}
return 0;
}
}
// find pos of first event which st value larger than x
int bsearch(Event[] e, int l, int r, int x) {
int mid = 0, ans = -1;
while (l <= r) {
mid = (l + r) >> 1;
if (e[mid].st > x) {
ans = mid;
r = mid - 1;
} else {
l = mid + 1;
}
}
return ans;
}
public int maxTwoEvents(int[][] events) {
int n = events.length;
Event[] e = new Event[n];
for (int i = 0; i < n; i++) {
e[i] = new Event(events[i][0], events[i][1], events[i][2]);
}
Arrays.sort(e);
int cur = 0;
int[] ma = new int[n];
for (int i = n - 1; i >= 0; i--) {
if (cur < e[i].val) {
cur = e[i].val;
}
ma[i] = cur;
}
int ans = 0;
for (int i = 0; i < n; i++) {
int pos = bsearch(e, i, n - 1, e[i].ed);
if (pos != -1) {
ans = Math.max(ans, e[i].val + ma[pos]);
}
}
return Math.max(ma[0], ans);
}
}