The Number of Full Rounds You Have Played
MedPrompt
You are participating in an online chess tournament. There is a chess round that starts every 15 minutes. The first round of the day starts at 00:00, and after every 15 minutes, a new round starts.
- For example, the second round starts at
00:15, the fourth round starts at00:45, and the seventh round starts at01:30.
You are given two strings loginTime and logoutTime where:
loginTimeis the time you will login to the game, andlogoutTimeis the time you will logout from the game.
If logoutTime is earlier than loginTime, this means you have played from loginTime to midnight and from midnight to logoutTime.
Return the number of full chess rounds you have played in the tournament.
Note: All the given times follow the 24-hour clock. That means the first round of the day starts at 00:00 and the last round of the day starts at 23:45.
Example 1:
Input: loginTime = "09:31", logoutTime = "10:14"
Output: 1
Explanation: You played one full round from 09:45 to 10:00.
You did not play the full round from 09:30 to 09:45 because you logged in at 09:31 after it began.
You did not play the full round from 10:00 to 10:15 because you logged out at 10:14 before it ended.Example 2:
Input: loginTime = "21:30", logoutTime = "03:00"
Output: 22
Explanation: You played 10 full rounds from 21:30 to 00:00 and 12 full rounds from 00:00 to 03:00.
10 + 12 = 22.
Constraints:
loginTimeandlogoutTimeare in the formathh:mm.00 <= hh <= 2300 <= mm <= 59loginTimeandlogoutTimeare not equal.
Approaches
2 approaches with complexity analysis and trade-offs.
This approach simulates the process of playing through the tournament. It first determines the actual playable time window, then iterates through all possible 15-minute round start times within that window, counting each one that can be fully completed.
Algorithm
- Parse the
loginTimeandlogoutTimestrings to get the total minutes from midnight for each. - Handle the case where the session spans midnight. If
logoutTimeis earlier thanloginTime, add a full day's worth of minutes (24 * 60 = 1440) to thelogoutTime's minute representation. - Calculate the start time of the first potential full round. This is done by rounding the
loginTime(in minutes) up to the next 15-minute mark. For example, a login at 09:31 means the first possible round starts at 09:45. - Initialize a counter for full rounds to zero.
- Iterate from the calculated start time, incrementing by 15 minutes in each step.
- In each iteration, check if the current round can be completed. A round starting at time
tends att + 15. This round is complete ift + 15is less than or equal to thelogoutTime(in minutes). - If the round is complete, increment the counter.
- Continue the loop until the round can no longer be completed.
- Return the final count.
Walkthrough
The core idea is to model the problem directly. We first convert the time strings into a more usable format, like total minutes from midnight. A key step is to handle sessions that cross midnight by adding 24 hours to the logout time, creating a single continuous timeline. Then, we find the first round we could possibly play by rounding our login time up to the next 15-minute mark. From this adjusted start time, we loop in 15-minute increments, checking if each full round (from t to t+15) ends before or at our logout time. We count every such round until they start extending past our logout time.
class Solution { public int numberOfRounds(String loginTime, String logoutTime) { int loginH = Integer.parseInt(loginTime.substring(0, 2)); int loginM = Integer.parseInt(loginTime.substring(3, 5)); int logoutH = Integer.parseInt(logoutTime.substring(0, 2)); int logoutM = Integer.parseInt(logoutTime.substring(3, 5)); int loginTotalMinutes = loginH * 60 + loginM; int logoutTotalMinutes = logoutH * 60 + logoutM; if (logoutTotalMinutes < loginTotalMinutes) { logoutTotalMinutes += 24 * 60; // Add a day for overnight session } // Round login time up to the next 15-minute mark int startRoundMinutes = (int) Math.ceil(loginTotalMinutes / 15.0) * 15; int count = 0; for (int t = startRoundMinutes; t + 15 <= logoutTotalMinutes; t += 15) { count++; } return count; }}Complexity
Time
O(1). Although there is a loop, the maximum number of iterations is fixed and small. A day has `24 * 4 = 96` rounds. An overnight session can span at most two days, so the loop runs at most `2 * 96 = 192` times, which is considered constant time.
Space
O(1). We only use a few integer variables to store the times and the count.
Trade-offs
Pros
Easy to understand and implement as it directly models the problem statement.
Correct for all cases and handles edge cases like overnight sessions properly.
Cons
Slightly less performant than a direct mathematical calculation due to the explicit loop.
The logic can be simplified into a single formula, making this approach more verbose than necessary.
This approach avoids iteration by directly calculating the number of full rounds using a mathematical formula. It converts the times to minutes, adjusts the start and end times to the nearest playable round boundaries, and then calculates the number of 15-minute intervals between them.
Algorithm
- Convert
loginTimeandlogoutTimestrings into total minutes from midnight. - If
logoutMinutes < loginMinutes, add1440(24 * 60) tologoutMinutesto handle the overnight case. - Calculate the effective start time (
start) by roundingloginMinutesup to the nearest multiple of 15. This can be done with integer arithmetic:start = (loginMinutes + 14) / 15. - Calculate the effective end time (
end) by roundinglogoutMinutesdown to the nearest multiple of 15. This can be done with integer arithmetic:end = logoutMinutes / 15. - The number of rounds is the difference between these two 15-minute block indices:
end - start. - Return the result, ensuring it's not negative (e.g., using
Math.max(0, result)).
Walkthrough
The most efficient way to solve this problem is to transform the time-based logic into a pure arithmetic problem. We convert both login and logout times into total minutes from midnight. To handle overnight sessions, if logout is earlier than login, we add a full day's minutes (1440) to the logout time.
The crucial step is to determine the actual interval of playable rounds. The first possible round must start at or after we log in. We find this by rounding the login time up to the next 15-minute mark. The last possible round must end at or before we log out, so we find this by rounding the logout time down to the previous 15-minute mark.
Once we have the adjusted start and end times in minutes, the number of rounds is simply the duration of this adjusted interval divided by 15. This entire process can be done with a few lines of code without any loops.
class Solution { public int numberOfRounds(String loginTime, String logoutTime) { // Helper to convert "hh:mm" to minutes from midnight int loginMinutes = toMinutes(loginTime); int logoutMinutes = toMinutes(logoutTime); // Handle overnight session if (logoutMinutes < loginMinutes) { logoutMinutes += 24 * 60; } // Round login time up to the nearest 15-minute interval // Example: 09:31 (571) -> (571 + 14) / 15 = 39. This is the 39th 15-min block. int startBlock = (loginMinutes + 14) / 15; // Round logout time down to the nearest 15-minute interval // Example: 10:14 (614) -> 614 / 15 = 40. This is the 40th 15-min block. int endBlock = logoutMinutes / 15; // The number of rounds is the difference in these 15-minute blocks int rounds = endBlock - startBlock; return Math.max(0, rounds); } private int toMinutes(String time) { int hours = Integer.parseInt(time.substring(0, 2)); int minutes = Integer.parseInt(time.substring(3, 5)); return hours * 60 + minutes; }}Complexity
Time
O(1). The solution involves a fixed number of arithmetic operations, regardless of the input times. String parsing and calculations are all constant time operations.
Space
O(1). Only a few variables are used to store the calculated minute values. No additional data structures are needed.
Trade-offs
Pros
Most efficient solution as it uses direct calculation without any loops.
Concise and elegant, reducing the problem to a few arithmetic operations.
Cons
The mathematical logic, especially the rounding using integer arithmetic, might be slightly less intuitive at first glance compared to an iterative approach.
Solutions
Solution
class Solution {public int numberOfRounds(String loginTime, String logoutTime) { int a = f(loginTime), b = f(logoutTime); if (a > b) { b += 1440; } return Math.max(0, b / 15 - (a + 14) / 15); }private int f(String s) { int h = Integer.parseInt(s.substring(0, 2)); int m = Integer.parseInt(s.substring(3, 5)); return h * 60 + m; }}class Solution {public: int numberOfRounds(string loginTime, string logoutTime) { auto f = [](string &s) { int h, m; sscanf(s.c_str(), "%d:%d", &h, &m); return h * 60 + m; }; int a = f(loginTime), b = f(logoutTime); if (a > b) { b += 1440; } return max(0, b / 15 - (a + 14) / 15); }};class Solution: def numberOfRounds(self, loginTime: str, logoutTime: str) -> int: def f(s: str) -> int: return int(s[: 2]) * 60 + int(s[3:]) a, b = f(loginTime), f(logoutTime) if a > b: b += 1440 a, b = (a + 14) // 15, b // 15 return max(0, b - a)Video walkthrough
Newsletter
One sharp idea, every week
System design and interview prep — short enough to finish.
No spam. Unsubscribe anytime.
Practice
Same difficulty — related problems to reinforce the pattern.