The solution uses Dynamic Programming with binary search to maximize the value of attended
events. First, we
sort
events by
endTime
to enable
efficient searching of
non-overlapping
events.
For each event, we use
binary search
to
find
the latest event
that doesn't overlap with the current one. The
DP table
stores the
maximum value achievable by attending up to
k events
. At each step,
we
choose
between
including the
current event
(plus the
best non-overlapping solution)
or excluding it. Finally, we
take the
maximum among all
possible cases.
class Event{ int startTime; int endTime; int value; Event(int start, int end, int profit){ this.startTime = start; this.endTime = end; this.value = profit; } } class Solution { // Binary Search public int srch(List<Event> allEvents, int event){ int start = 0; int end = event-1; int ans = -1; while(start<=end){ int mid = (start+end)/2; if(allEvents.get(mid).endTime < allEvents.get(event).startTime){ ans = mid; start = mid+1; } else end = mid-1; } return ans; } public int maxValue(int[][] events, int k) { int noOfEvents = events.length; List<Event> allEvents = new ArrayList<>(); for(int i=0;i<events.length;i++){ allEvents.add(new Event(events[i][0],events[i][1],events[i][2])); } // Sort based on End Time Collections.sort(allEvents, (a,b)->Integer.compare(a.endTime,b.endTime)); int[][] maxProfit = new int[noOfEvents+1][k+1]; for(int i=0;i<=noOfEvents;i++){ for(int j=0;j<=k;j++){ if(i==0 || j==0) maxProfit[i][j] = 0; else{ int nextPermissibleEvent = srch(allEvents,i-1); int include = allEvents.get(i-1).value; // Note: nextPermissibleEvent+1 is mistake point. // Bec. nextPermissibleEvent idx will come as zero based. if(nextPermissibleEvent!=-1) include += maxProfit[nextPermissibleEvent+1][j-1]; int exclude = maxProfit[i-1][j]; maxProfit[i][j] = Math.max(include,exclude); } } } return maxProfit[noOfEvents][k]; } }
Sorting takes O(n log n) and DP with binary search takes O(nk log n) where n is number of events and k is maximum events to attend.
The DP table requires O(nk) space, and sorting requires O(log n) stack space.