You are given an integer eventTime denoting the duration of an event, where the event occurs from time t = 0 to time t = eventTime.
You are also given two integer arrays startTime and endTime, each of length n. These represent the start and end time of n non-overlapping meetings, where the ith meeting occurs during the time [startTime[i], endTime[i]].
You can reschedule at mostk meetings by moving their start time while maintaining the same duration, to maximize the longest continuous period of free time during the event.
The relative order of all the meetings should stay the same and they should remain non-overlapping. Return the maximum amount of free time possible after rearranging the meetings.
Note that the meetings can not be rescheduled to a time outside the event.
💡 Note:Original gaps are [10,10,20]. By moving the meeting [60,80] to [0,20], we create gaps [20,10,20] with maximum 20. Better: move [10,20] to [80,90] creating gaps [30,20,10] with maximum 30.
💡 Note:Only one meeting exists. The maximum gap is either before (10 units) or after (30 units) the meeting. Since k=2 > number of meetings, we can move it optimally to get gap of 30.
💡 Note:Move first two meetings to create large continuous gap. Moving [20,40] and [60,80] to positions [0,20] and [180,200] creates a gap of 100 units from 20 to 120.
Reschedule Meetings for Maximum Free Time I — Solution
The key insight is to identify which meetings provide maximum free time gain when rescheduled. The greedy approach calculates the benefit of moving each meeting and selects the top k candidates. Best approach uses greedy optimization with Time: O(n log n), Space: O(n).
Common Approaches
✓
Brute Force
⏱️ Time: O(C(n,k) × n^k × n)
Space: O(n)
Generate all possible combinations of k meetings to reschedule, try all valid positions for each combination, and calculate the maximum free time for each arrangement.
Greedy Optimization
⏱️ Time: O(n log n)
Space: O(n)
Calculate the potential free time gain from moving each meeting, then greedily select the k meetings that provide the maximum cumulative benefit when rescheduled optimally.
Sliding Window with Greedy
⏱️ Time: O(n² × k)
Space: O(n)
Calculate all gaps in the current schedule, use a sliding window approach to identify the largest potential free time block, then greedily reschedule meetings to maximize this block.
Brute Force — Algorithm Steps
Generate all combinations of k meetings to reschedule
For each combination, try all valid positions
Calculate maximum continuous free time for each arrangement
Return the maximum across all possibilities
Visualization
Tap to expand
Step-by-Step Walkthrough
1
Generate Combinations
Create all possible sets of k meetings to reschedule
2
Try Positions
For each combination, try all valid time positions
3
Calculate Gaps
Find maximum free time gap for each arrangement
4
Return Maximum
Select the arrangement with largest continuous free time
Code -
solution.c — C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
int start;
int end;
} Meeting;
static int maxFreeTime = 0;
static Meeting meetings[1000];
static int durations[1000];
static int rescheduleIndices[1000];
static int rescheduleDurations[1000];
static Meeting currentMeetings[1000];
static Meeting fixedMeetings[1000];
int compare(const void* a, const void* b) {
Meeting* m1 = (Meeting*)a;
Meeting* m2 = (Meeting*)b;
return m1->start - m2->start;
}
int isValidArrangement(Meeting* meetings, int n, int eventTime) {
qsort(meetings, n, sizeof(Meeting), compare);
for (int i = 0; i < n; i++) {
if (meetings[i].start < 0 || meetings[i].end > eventTime) return 0;
if (i > 0 && meetings[i].start < meetings[i-1].end) return 0;
}
return 1;
}
int calculateMaxFreeTime(Meeting* meetings, int n, int eventTime) {
if (n == 0) return eventTime;
qsort(meetings, n, sizeof(Meeting), compare);
int maxGap = meetings[0].start;
for (int i = 1; i < n; i++) {
int gap = meetings[i].start - meetings[i-1].end;
if (gap > maxGap) maxGap = gap;
}
int gap = eventTime - meetings[n-1].end;
if (gap > maxGap) maxGap = gap;
return maxGap;
}
void backtrack(int eventTime, Meeting* fixed, int fixedCount, int* rescheduleDur, int rescheduleDurCount, int idx, Meeting* current, int currentCount) {
if (idx == rescheduleDurCount) {
Meeting temp[1000];
for (int i = 0; i < currentCount; i++) {
temp[i] = current[i];
}
if (isValidArrangement(temp, currentCount, eventTime)) {
for (int i = 0; i < currentCount; i++) {
temp[i] = current[i];
}
int freeTime = calculateMaxFreeTime(temp, currentCount, eventTime);
if (freeTime > maxFreeTime) {
maxFreeTime = freeTime;
}
}
return;
}
int duration = rescheduleDur[idx];
int step = eventTime / 100;
if (step < 1) step = 1;
for (int start = 0; start <= eventTime - duration; start += step) {
current[currentCount].start = start;
current[currentCount].end = start + duration;
Meeting temp[1000];
for (int i = 0; i <= currentCount; i++) {
temp[i] = current[i];
}
if (isValidArrangement(temp, currentCount + 1, eventTime)) {
backtrack(eventTime, fixed, fixedCount, rescheduleDur, rescheduleDurCount, idx + 1, current, currentCount + 1);
}
}
}
void generateCombinations(int* startTime, int* endTime, int* dur, int eventTime, int n, int numReschedule, int start, int* current, int currentSize) {
if (currentSize == numReschedule) {
int fixedCount = 0;
int rescheduleDurCount = 0;
for (int i = 0; i < n; i++) {
int found = 0;
for (int j = 0; j < currentSize; j++) {
if (current[j] == i) {
found = 1;
break;
}
}
if (!found) {
fixedMeetings[fixedCount].start = startTime[i];
fixedMeetings[fixedCount].end = endTime[i];
fixedCount++;
} else {
rescheduleDurations[rescheduleDurCount] = dur[i];
rescheduleDurCount++;
}
}
for (int i = 0; i < fixedCount; i++) {
currentMeetings[i] = fixedMeetings[i];
}
backtrack(eventTime, fixedMeetings, fixedCount, rescheduleDurations, rescheduleDurCount, 0, currentMeetings, fixedCount);
return;
}
for (int i = start; i < n; i++) {
current[currentSize] = i;
generateCombinations(startTime, endTime, dur, eventTime, n, numReschedule, i + 1, current, currentSize + 1);
}
}
int solution(int eventTime, int* startTime, int* endTime, int n, int k) {
if (n == 0) return eventTime;
for (int i = 0; i < n; i++) {
durations[i] = endTime[i] - startTime[i];
}
maxFreeTime = 0;
int maxReschedule = k < n ? k : n;
for (int numReschedule = 0; numReschedule <= maxReschedule; numReschedule++) {
int current[1000];
generateCombinations(startTime, endTime, durations, eventTime, n, numReschedule, 0, current, 0);
}
return maxFreeTime;
}
int main() {
int eventTime, k;
scanf("%d", &eventTime);
char line[1000];
fgets(line, sizeof(line), stdin); // consume newline
fgets(line, sizeof(line), stdin);
// Parse start times
int startTime[100], n = 0;
char* p = line;
while (*p && *p != '[') p++;
if (*p == '[') p++;
while (*p && *p != ']') {
while (*p == ' ' || *p == ',') p++;
if (*p == ']' || *p == '\0' || *p == '\n') break;
char* endPtr;
int val = (int)strtol(p, &endPtr, 10);
if (endPtr != p) {
startTime[n++] = val;
p = endPtr;
} else {
p++;
}
}
fgets(line, sizeof(line), stdin);
int endTime[100];
p = line;
while (*p && *p != '[') p++;
if (*p == '[') p++;
int idx = 0;
while (*p && *p != ']' && idx < n) {
while (*p == ' ' || *p == ',') p++;
if (*p == ']' || *p == '\0' || *p == '\n') break;
char* endPtr;
int val = (int)strtol(p, &endPtr, 10);
if (endPtr != p) {
endTime[idx++] = val;
p = endPtr;
} else {
p++;
}
}
scanf("%d", &k);
int result = solution(eventTime, startTime, endTime, n, k);
printf("%d\n", result);
return 0;
}
Time & Space Complexity
Time Complexity
⏱️
O(C(n,k) × n^k × n)
C(n,k) combinations × n^k positions × n time to check gaps
n
2n
⚠ Quadratic Growth
Space Complexity
O(n)
Store meeting arrangements and calculate gaps
n
2n
⚡ Linearithmic Space
27.1K Views
MediumFrequency
~25 minAvg. Time
847 Likes
Ln 1, Col 1
Smart Actions
💡Explanation
AI Ready
💡 SuggestionTabto acceptEscto dismiss
// Output will appear here after running code
Code Editor Closed
Click the red button to reopen
Algorithm Visualization
Pinch to zoom • Tap outside to close
Test Cases
0 passed
0 failed
3 pending
Select Compiler
Choose a programming language
Compiler list would appear here...
AI Editor Features
Header Buttons
💡
Explain
Get a detailed explanation of your code. Select specific code or analyze the entire file. Understand algorithms, logic flow, and complexity.
🔧
Fix
Automatically detect and fix issues in your code. Finds bugs, syntax errors, and common mistakes. Shows you what was fixed.
💡
Suggest
Get improvement suggestions for your code. Best practices, performance tips, and code quality recommendations.
💬
Ask AI
Open an AI chat assistant to ask any coding questions. Have a conversation about your code, get help with debugging, or learn new concepts.
Smart Actions (Slash Commands)
🔧
/fix Enter
Find and fix issues in your code. Detects common problems and applies automatic fixes.
💡
/explain Enter
Get a detailed explanation of what your code does, including time/space complexity analysis.
🧪
/tests Enter
Automatically generate unit tests for your code. Creates comprehensive test cases.
📝
/docs Enter
Generate documentation for your code. Creates docstrings, JSDoc comments, and type hints.
⚡
/optimize Enter
Get performance optimization suggestions. Improve speed and reduce memory usage.
AI Code Completion (Copilot-style)
👻
Ghost Text Suggestions
As you type, AI suggests code completions shown in gray text. Works with keywords like def, for, if, etc.
Tabto acceptEscto dismiss
💬
Comment-to-Code
Write a comment describing what you want, and AI generates the code. Try: # two sum, # binary search, # fibonacci
💡
Pro Tip: Select specific code before using Explain, Fix, or Smart Actions to analyze only that portion. Otherwise, the entire file will be analyzed.