Want Help Cracking FAANG?

(Then click this)

×
Back to Question Bank

1904. The Number of Full Rounds You Have Played - Leetcode Solution

Problem Description

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.

  • Input: Two strings startTime and finishTime in 24-hour format.
  • Output: An integer representing the number of full 15-minute rounds played.
  • Constraints: Both times are valid, and the interval may cross midnight.

Thought Process

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:

  • Convert both times to minutes since midnight for easy calculation.
  • Round 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.
  • Round 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.
  • Count the number of 15-minute intervals between these two adjusted times.
If the session crosses midnight, we handle the wrap-around by adding 24 hours (1440 minutes) to the finish time.

Solution Approach

Here is a step-by-step breakdown of the optimized solution:

  1. Convert Times to Minutes:
    • Parse startTime and finishTime into hours and minutes.
    • Calculate total minutes since midnight for both times.
  2. Handle Overnight Sessions:
    • If finishTime is less than startTime, add 24 * 60 minutes to finishTime to account for the next day.
  3. Round Times to Nearest 15-Minute Marks:
    • Round startTime up to the next 15-minute interval (if not already on one).
    • Round finishTime down to the previous 15-minute interval (if not already on one).
  4. Count Full Rounds:
    • Subtract the adjusted startTime from finishTime.
    • Divide the difference by 15 to get the number of full rounds.
    • If the result is negative, return 0 (no full rounds).

This approach is efficient and avoids unnecessary looping or checking of each interval.

Example Walkthrough

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.

Time and Space Complexity

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.

Summary

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.

Code Implementation

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);
};