Want Help Cracking FAANG?

(Then click this)

×
Back to Question Bank

681. Next Closest Time - Leetcode Solution

Code Implementation

class Solution:
    def nextClosestTime(self, time: str) -> str:
        allowed = set(time.replace(":", ""))
        cur_minutes = int(time[:2]) * 60 + int(time[3:])
        for i in range(1, 1441):
            next_minutes = (cur_minutes + i) % 1440
            h, m = divmod(next_minutes, 60)
            next_time = f"{h:02d}:{m:02d}"
            if set(next_time.replace(":", "")) > allowed:
                continue
            if all(c in allowed for c in next_time.replace(":", "")):
                return next_time
        return time
      
class Solution {
public:
    string nextClosestTime(string time) {
        set<char> allowed;
        for (char c : time) if (c != ':') allowed.insert(c);
        int cur_minutes = stoi(time.substr(0, 2)) * 60 + stoi(time.substr(3, 2));
        for (int i = 1; i <= 1440; ++i) {
            int next = (cur_minutes + i) % 1440;
            int h = next / 60, m = next % 60;
            char buf[6];
            sprintf(buf, "%02d:%02d", h, m);
            string next_time(buf);
            bool valid = true;
            for (char c : next_time) {
                if (c == ':') continue;
                if (!allowed.count(c)) {
                    valid = false;
                    break;
                }
            }
            if (valid) return next_time;
        }
        return time;
    }
};
      
class Solution {
    public String nextClosestTime(String time) {
        Set<Character> allowed = new HashSet<>();
        for (char c : time.toCharArray()) if (c != ':') allowed.add(c);
        int curMinutes = Integer.parseInt(time.substring(0, 2)) * 60 + Integer.parseInt(time.substring(3, 5));
        for (int i = 1; i <= 1440; ++i) {
            int next = (curMinutes + i) % 1440;
            int h = next / 60, m = next % 60;
            String nextTime = String.format("%02d:%02d", h, m);
            boolean valid = true;
            for (char c : nextTime.toCharArray()) {
                if (c == ':') continue;
                if (!allowed.contains(c)) {
                    valid = false;
                    break;
                }
            }
            if (valid) return nextTime;
        }
        return time;
    }
}
      
var nextClosestTime = function(time) {
    let allowed = new Set(time.replace(":", "").split(""));
    let curMinutes = parseInt(time.slice(0,2)) * 60 + parseInt(time.slice(3,5));
    for (let i = 1; i <= 1440; ++i) {
        let next = (curMinutes + i) % 1440;
        let h = Math.floor(next / 60);
        let m = next % 60;
        let nextTime = (h < 10 ? "0" : "") + h + ":" + (m < 10 ? "0" : "") + m;
        if ([...nextTime.replace(":", "")].every(c => allowed.has(c))) {
            return nextTime;
        }
    }
    return time;
};
      

Problem Description

Given a time in 24-hour format as a string time (e.g. "19:34"), find the next closest time that can be formed by reusing the digits from the original time. You can use each digit as many times as needed. The returned time must be a valid 24-hour time (i.e., "00:00" to "23:59") and must be strictly greater than the given time. If no such time exists on the same day, wrap around to the earliest possible time on the next day. There is always at least one valid answer.

Thought Process

At first glance, the problem seems to ask for generating all possible combinations of the original digits and checking which ones form valid times. However, since the allowed digits are limited, and we can repeat them, the total number of possible times is small (at most 4 digits, so 44 = 256 combinations).

The brute-force approach would be to generate all possible times, sort them, and pick the next one after the current time. But we can optimize by simulating minute-by-minute increments from the current time, checking at each step if the new time uses only allowed digits. Since there are only 1440 minutes in a day, this is efficient.

Solution Approach

To solve the problem efficiently, we follow these steps:
  1. Extract Allowed Digits: Remove the colon from the input and collect the set of digits we can use.
  2. Convert Time to Minutes: Change the given time into the number of minutes since midnight. This makes it easy to increment the time and handle wrap-around at midnight.
  3. Minute-by-Minute Simulation: Starting from the next minute, increment the time by one minute. For each new time, check if every digit in the time is in the set of allowed digits.
  4. Check Validity: If the new time uses only allowed digits, return it as the answer.
  5. Wrap Around: If we reach 24 hours (1440 minutes), wrap around to the start of the day. Since there is always a valid answer, this loop is guaranteed to terminate.
This approach is simple, avoids unnecessary combinations, and leverages the small search space.

Example Walkthrough

Let's use the input time = "19:34".

  • Allowed digits: 1, 3, 4, 9
  • Current time in minutes: 19 * 60 + 34 = 1174
  • Start checking minute by minute:
  • 1175: 19:35 (digits: 1, 9, 3, 5) - 5 not allowed
  • 1176: 19:36 (digits: 1, 9, 3, 6) - 6 not allowed
  • ... (continue checking) ...
  • 1199: 19:59 (digits: 1, 9, 5, 9) - 5 not allowed
  • 1200: 20:00 (digits: 2, 0, 0, 0) - 2,0 not allowed
  • ... (continue until next valid time) ...
  • 1319: 21:39 (digits: 2, 1, 3, 9) - 2 not allowed
  • ... (eventually reaches 19:41, 19:44, etc.) ...
  • Eventually, the next valid time is 19:39 (digits: 1, 9, 3, 9) - all allowed
  • So the answer is "19:39".

Time and Space Complexity

  • Brute-force approach: Generate all 256 possible times (4 digits, 4 choices each), filter valid ones, sort, and pick the next. Time: O(256) = O(1), Space: O(256) = O(1).
  • Minute-by-minute approach (used here): At most 1440 iterations (one for each minute in a day). For each, checking 4 digits. Time: O(1440 * 4) = O(1), Space: O(1).
Both approaches are constant time and space in practice due to the small problem size, but the minute-by-minute simulation is conceptually simpler and avoids sorting.

Summary

This problem leverages the small number of possible times you can form with 4 digits. By simulating each minute after the current time and checking if its digits are allowed, we efficiently find the next closest valid time. The solution is elegant because it avoids unnecessary computation, is easy to implement, and guarantees a result thanks to the finite search space.