Given a time represented in the format "HH:MM"
, form the next closest time by reusing the current digits. There is no limit on how many times a digit can be reused.
You are allowed to rearrange the digits, and you must use all four digits.
Produce the next closest time in the format "HH:MM"
.
Example 1:
Input: time = "19:34"
Output: "19:39"
Explanation: The next closest time choosing from digits 1, 9, 3, 4 is 19:39, which occurs 5 minutes later.
It is not 19:31, because this occurs 23 hours and 57 minutes later.
Example 2:
Input: time = "23:59"
Output: "22:22"
Explanation: The next closest time choosing from digits 2, 3, 5, 9 is 22:22. It may be assumed that the returned time is next day's time since it is the nearest.
Constraints:
time
is a valid time represented in the format "HH:MM"
.When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force approach to finding the next closest time involves generating every possible time using the digits from the input time. Then, we check each generated time to see if it's valid and later than the input time. Finally, we pick the smallest valid time that is later than the input.
Here's how the algorithm would work step-by-step:
def next_closest_time(time):
allowed_digits = set(time[:2] + time[3:])
current_hour = int(time[:2])
current_minute = int(time[3:])
closest_time = None
for first_digit in allowed_digits:
for second_digit in allowed_digits:
for third_digit in allowed_digits:
for fourth_digit in allowed_digits:
possible_hour = int(first_digit + second_digit)
possible_minute = int(third_digit + fourth_digit)
# We need to make sure the generated time is valid
if possible_hour >= 0 and possible_hour <= 23 and \
possible_minute >= 0 and possible_minute <= 59:
possible_time_total_minutes = possible_hour * 60 + possible_minute
current_time_total_minutes = current_hour * 60 + current_minute
if possible_time_total_minutes > current_time_total_minutes:
if closest_time is None:
closest_time = "%02d:%02d" % (possible_hour, possible_minute)
else:
closest_hour = int(closest_time[:2])
closest_minute = int(closest_time[3:])
closest_time_total_minutes = closest_hour * 60 + closest_minute
if possible_time_total_minutes < closest_time_total_minutes:
closest_time = "%02d:%02d" % (possible_hour, possible_minute)
# If no time is greater, find the smallest time possible
if closest_time is None:
allowed_digits_list = sorted(list(allowed_digits))
closest_time = allowed_digits_list[0] + allowed_digits_list[0] + ":" + allowed_digits_list[0] + allowed_digits_list[0]
return closest_time
The goal is to find the smallest time that can be formed using the digits from the given time, and that is also later than the given time. Instead of checking every possible time combination, we can build the next closest time digit by digit, starting from the rightmost digit.
Here's how the algorithm would work step-by-step:
def next_closest_time(time):
current_hour = int(time[0:2])
current_minute = int(time[3:5])
digits = {time[0], time[1], time[3], time[4]}
all_possible_times = sorted(hour + ':' + minute
for hour in (d1 + d2 for d1 in digits for d2 in digits)
for minute in (d3 + d4 for d3 in digits for d4 in digits)
if hour <= '23' and minute <= '59')
current_time = time[0:2] + ':' + time[3:5]
next_time = min(t for t in all_possible_times if t > current_time, default=all_possible_times[0])
return next_time
def next_closest_time_original(time):
available_digits = sorted(set(time))
available_digits.remove(':')
current_hour = int(time[:2])
current_minute = int(time[3:])
while True:
current_minute += 1
if current_minute == 60:
current_minute = 0
current_hour += 1
if current_hour == 24:
current_hour = 0
hour_string = str(current_hour).zfill(2)
minute_string = str(current_minute).zfill(2)
new_time = hour_string + minute_string
is_valid = True
for digit in new_time:
if digit not in available_digits:
is_valid = False
break
if is_valid:
return hour_string + ':' + minute_string
def next_closest_time_detailed(time):
available_digits = sorted(set(time))
available_digits.remove(':')
hour_tens = int(time[0])
hour_ones = int(time[1])
minute_tens = int(time[3])
minute_ones = int(time[4])
while True:
minute_ones = find_next_greater(minute_ones, available_digits, 9)
if minute_ones is None:
minute_ones = int(available_digits[0])
minute_tens = find_next_greater(minute_tens, available_digits, 5)
if minute_tens is None:
minute_tens = int(available_digits[0])
hour_ones = find_next_greater(hour_ones, available_digits, 9 if hour_tens < 2 else 3)
if hour_ones is None:
hour_ones = int(available_digits[0])
hour_tens = find_next_greater(hour_tens, available_digits, 2)
if hour_tens is None:
# We need to start over from the smallest possible time
hour_tens = int(available_digits[0])
hour_ones = int(available_digits[0])
minute_tens = int(available_digits[0])
minute_ones = int(available_digits[0])
hour = hour_tens * 10 + hour_ones
if hour < 24:
#Ensure this is a valid hour before returning.
break
return str(hour_tens) + str(hour_ones) + ':' + str(minute_tens) + str(minute_ones)
def find_next_greater(current_digit, available_digits, limit):
for digit in available_digits:
digit = int(digit)
if digit > current_digit and digit <= limit:
return digit
return None
Case | How to Handle |
---|---|
Null or empty input time string | Return null or throw IllegalArgumentException, as a valid time cannot be derived. |
Input time string is invalid format (e.g., missing colon, incorrect length) | Throw IllegalArgumentException as parsing will fail and the time digits cannot be extracted. |
All digits in the input time are the same (e.g., '11:11') | The algorithm must correctly find the next valid time using this single available digit by wrapping around when needed. |
The provided digits cannot form a valid time (e.g., digits are 4, 5, 6, 7) | The algorithm should wrap around to the smallest possible valid time that can be formed with available digits, like '00:00' if 0 is available. |
Input time is '23:59' | The next closest time must correctly wrap around to the earliest possible time composed of available digits. |
Integer overflow when calculating possible next times | The algorithm should use string manipulation to avoid integer overflow when generating and comparing times. |
Time contains non-digit characters | Throw an exception, or filter down to valid digit characters and continue. |
Only one unique digit is provided, and that digit can only be used in one location, creating an impossible scenario for some time components | Algorithm should handle constraints such as the tens place for hours only having a digit from 0-2 available within the provided digits. |