The problem "The Number of Full Rounds You Have Played" asks you to determine how many full 15-minute rounds a player has played between two specified times on the same day.
You are given two strings, startTime
and finishTime
, both in the format "HH:MM"
representing the start and end times in a 24-hour format.
A round is considered "full" if it starts and ends at a time that is a multiple of 15 minutes (e.g., 00:00, 00:15, 00:30, 00:45, etc.), and the player has played for the entire duration of the round.
If the finishTime
is earlier than startTime
, it means the session ended on the next day.
The goal is to count the number of complete 15-minute intervals fully contained within the session.
startTime
and finishTime
in 24-hour format.
The initial idea is to simply count every 15-minute interval between the two times. However, the tricky part is that partial intervals at the start or end do not count. Only intervals that are fully covered by the play session are counted.
A brute-force approach would be to check every possible 15-minute interval between the two times, but this is inefficient and unnecessary.
To optimize, we can:
startTime
up to the next 15-minute mark (if it's not already on one), since a round can't start before the session does.finishTime
down to the previous 15-minute mark (if it's not already on one), since a round can't end after the session ends.Here is a step-by-step breakdown of the optimized solution:
startTime
and finishTime
into hours and minutes.finishTime
is less than startTime
, add 24 * 60 minutes to finishTime
to account for the next day.startTime
up to the next 15-minute interval (if not already on one).finishTime
down to the previous 15-minute interval (if not already on one).startTime
from finishTime
.This approach is efficient and avoids unnecessary looping or checking of each interval.
Let's walk through an example:
Input: startTime = "12:01"
, finishTime = "12:44"
Step 1: Convert to Minutes
startTime
: 12 * 60 + 1 = 721 minutes
finishTime
: 12 * 60 + 44 = 764 minutes
Step 2: Round to Nearest 15-Minute Mark
startTime
rounded up: next 15-minute mark after 721 is 12:15 (12*60+15=735)
finishTime
rounded down: previous 15-minute mark before 764 is 12:45 (12*60+45=765), but since 764 < 765, use 12:30 (12*60+30=750)
Step 3: Count Full Rounds
Number of minutes: 750 - 735 = 15
Number of rounds: 15 / 15 = 1
Output: 1
Explanation: Only one full 15-minute round (12:15-12:30) is fully played.
Brute-force Approach:
If you checked every minute between the two times and counted full 15-minute intervals, the time complexity would be O(N), where N is the number of minutes in the interval (up to 1440).
Optimized Approach:
The optimized solution only does a constant number of arithmetic operations and comparisons, so the time complexity is O(1).
Space complexity is also O(1) since we only use a few integer variables.
The key to solving "The Number of Full Rounds You Have Played" is to correctly align both start and end times to the nearest 15-minute marks, handling the possibility of crossing midnight. By converting times to minutes, rounding appropriately, and using simple arithmetic, we efficiently count the number of full rounds without unnecessary iteration. This approach is both elegant and optimal for the problem constraints.
class Solution:
def numberOfRounds(self, startTime: str, finishTime: str) -> int:
def to_minutes(t):
h, m = map(int, t.split(":"))
return h * 60 + m
start = to_minutes(startTime)
end = to_minutes(finishTime)
if end < start:
end += 24 * 60
# Round start up to next 15-minute mark
if start % 15 != 0:
start = ((start // 15) + 1) * 15
# Round end down to previous 15-minute mark
end = (end // 15) * 15
res = (end - start) // 15
return max(res, 0)
class Solution {
public:
int numberOfRounds(string startTime, string finishTime) {
auto toMinutes = [](const string& t) {
int h = stoi(t.substr(0, 2));
int m = stoi(t.substr(3, 2));
return h * 60 + m;
};
int start = toMinutes(startTime);
int end = toMinutes(finishTime);
if (end < start) end += 24 * 60;
if (start % 15 != 0)
start = ((start / 15) + 1) * 15;
end = (end / 15) * 15;
int res = (end - start) / 15;
return max(res, 0);
}
};
class Solution {
public int numberOfRounds(String startTime, String finishTime) {
int toMinutes(String t) {
return Integer.parseInt(t.substring(0,2)) * 60 + Integer.parseInt(t.substring(3,5));
}
int start = toMinutes(startTime);
int end = toMinutes(finishTime);
if (end < start) end += 24 * 60;
if (start % 15 != 0)
start = ((start / 15) + 1) * 15;
end = (end / 15) * 15;
int res = (end - start) / 15;
return Math.max(res, 0);
}
}
var numberOfRounds = function(startTime, finishTime) {
function toMinutes(t) {
let [h, m] = t.split(":").map(Number);
return h * 60 + m;
}
let start = toMinutes(startTime);
let end = toMinutes(finishTime);
if (end < start) end += 24 * 60;
if (start % 15 !== 0)
start = Math.ceil(start / 15) * 15;
end = Math.floor(end / 15) * 15;
let res = Math.floor((end - start) / 15);
return Math.max(res, 0);
};