In real-world scheduling scenarios, there's often flexibility in meeting times. LeetCode 3440 explores a variation where you're allowed to reschedule one meeting to potentially maximize your continuous free time during a larger event. Unlike its predecessor, the relative order of meetings can now be changed. This introduces an interesting optimization problem that mixes greedy scanning with intelligent rescheduling.
🧠 Problem Summary
You are given:
- An integer
eventTime
, representing the full span of the event (fromt = 0
tot = eventTime
). - Two arrays:
startTime[]
andendTime[]
, where each pair defines the start and end times ofn
non-overlapping meetings.
You can reschedule at most one meeting (by changing its start time but keeping its duration the same), as long as:
- The new time doesn't exceed event bounds.
- Meetings stay non-overlapping.
Goal: Maximize the longest continuous free time after such rescheduling.
🔧 Intuition
The main idea is to:
- Traverse from left to right, tracking the largest gap before each meeting.
- Traverse from right to left, tracking the largest gap after each meeting.
- At each step, determine the maximum free block achievable by shifting a meeting into a known gap.
The meeting durations stay fixed. By checking if we can fit a meeting into a larger previous or subsequent gap, we determine the best possible outcome.
💪 C++ Code
#include <ranges>
class Solution {
public:
int maxFreeTime(int eventTime, vector<int>& startTime, vector<int>& endTime) {
int n = startTime.size();
int max_gap_before = 0;
int last_end = 0;
int max_free_time = 0;
for (int i = 0; i < n; ++i) {
int meeting_time = endTime[i] - startTime[i];
int next_start = (i == n - 1) ? eventTime : startTime[i + 1];
int free_time = next_start - last_end;
if (meeting_time > max_gap_before) free_time -= meeting_time;
max_free_time = max(max_free_time, free_time);
max_gap_before = max(max_gap_before, startTime[i] - last_end);
last_end = endTime[i];
}
int max_gap_after = 0;
int last_start = eventTime;
for (int i = n - 1; i >= 0; --i) {
int meeting_time = endTime[i] - startTime[i];
int prev_end = (i == 0) ? 0 : endTime[i - 1];
int free_time = last_start - prev_end;
if (meeting_time <= max_gap_after)
max_free_time = max(max_free_time, free_time);
max_gap_after = max(max_gap_after, last_start - endTime[i]);
last_start = startTime[i];
}
return max_free_time;
}
};
🐍 Python Code
class Solution:
def maxFreeTime(self, eventTime: int, startTime: List[int], endTime: List[int]) -> int:
n = len(startTime)
max_gap_before, max_free_time, last_end = 0, 0, 0
for i in range(n):
meeting_time = endTime[i] - startTime[i]
next_start = eventTime if i == n - 1 else startTime[i + 1]
free_time = next_start - last_end
if meeting_time > max_gap_before:
free_time -= meeting_time
max_free_time = max(max_free_time, free_time)
max_gap_before = max(max_gap_before, startTime[i] - last_end)
last_end = endTime[i]
max_gap_after, last_start = 0, eventTime
for i in reversed(range(n)):
meeting_time = endTime[i] - startTime[i]
prev_end = 0 if i == 0 else endTime[i - 1]
free_time = last_start - prev_end
if meeting_time <= max_gap_after:
max_free_time = max(max_free_time, free_time)
max_gap_after = max(max_gap_after, last_start - endTime[i])
last_start = startTime[i]
return max_free_time
🔌 JavaScript Code
var maxFreeTime = function(eventTime, startTime, endTime) {
let n = startTime.length;
let maxGapBefore = 0, maxFreeTime = 0, lastEnd = 0;
for (let i = 0; i < n; i++) {
let duration = endTime[i] - startTime[i];
let nextStart = (i === n - 1) ? eventTime : startTime[i + 1];
let freeTime = nextStart - lastEnd;
if (duration > maxGapBefore) freeTime -= duration;
maxFreeTime = Math.max(maxFreeTime, freeTime);
maxGapBefore = Math.max(maxGapBefore, startTime[i] - lastEnd);
lastEnd = endTime[i];
}
let maxGapAfter = 0, lastStart = eventTime;
for (let i = n - 1; i >= 0; i--) {
let duration = endTime[i] - startTime[i];
let prevEnd = (i === 0) ? 0 : endTime[i - 1];
let freeTime = lastStart - prevEnd;
if (duration <= maxGapAfter)
maxFreeTime = Math.max(maxFreeTime, freeTime);
maxGapAfter = Math.max(maxGapAfter, lastStart - endTime[i]);
lastStart = startTime[i];
}
return maxFreeTime;
};
📝 Key Takeaways
- Forward and reverse traversal helps us identify optimal gaps.
- Keep track of the largest gaps before and after each position.
- The ability to break order adds complexity but increases optimization potential.
- Avoid brute force. This solution runs in O(n) with no heap or segment trees.
✅ Final Thoughts
This variant of the rescheduling problem showcases the power of greedy planning and gap analysis. Real-life calendar apps, conference schedulers, or even logistics timelines could benefit from such logic. It's not always about cramming more into the schedule — sometimes it's about creating meaningful free time.
Let this pattern guide your approach in future scheduling problems!
Top comments (3)
Well Explained
Thanks Anna
Some comments may only be visible to logged-in visitors. Sign in to view all comments.