You are given the customer visit log of a shop represented by a 0-indexed string customers
consisting only of characters 'N'
and 'Y'
:
i
th character is 'Y'
, it means that customers come at the i
th hour'N'
indicates that no customers come at the i
th hour.If the shop closes at the j
th hour (0 <= j <= n
), the penalty is calculated as follows:
1
.1
.Return the earliest hour at which the shop must be closed to incur a minimum penalty.
Note that if a shop closes at the j
th hour, it means the shop is closed at the hour j
.
For example, given the input customers = "YYNY"
, the output should be 2
.
Explanation:
Closing the shop at 2nd or 4th hour gives a minimum penalty. Since 2 is earlier, the optimal closing time is 2.
Can you provide an efficient algorithm to solve this problem?
The brute force solution iterates through all possible closing hours and calculates the penalty for each hour. It then returns the hour with the minimum penalty. This involves nested loops, leading to a higher time complexity.
min_penalty
to infinity and earliest_hour
to 0.j
from 0 to n
(inclusive), where n
is the length of the customers
string.j
, calculate the penalty:
j-1
: If customers[i]
is 'N', increment the penalty (shop is open, no customer).j
to n-1
: If customers[i]
is 'Y', increment the penalty (shop is closed, customer arrives).min_penalty
, update min_penalty
and earliest_hour
.earliest_hour
.def earliest_closing_brute_force(customers):
n = len(customers)
min_penalty = float('inf')
earliest_hour = 0
for j in range(n + 1):
penalty = 0
for i in range(j):
if customers[i] == 'N':
penalty += 1
for i in range(j, n):
if customers[i] == 'Y':
penalty += 1
if penalty < min_penalty:
min_penalty = penalty
earliest_hour = j
return earliest_hour
The optimal solution utilizes a prefix sum approach to calculate the penalty in O(n) time. We can precompute the number of 'Y's and 'N's to avoid redundant calculations within the loop.
min_penalty
to infinity and earliest_hour
to 0.customers
string.customers
string:
customers[i]
is 'Y', decrement the current penalty (because if we close the shop after this hour, we will not count this customer in the penalty).customers[i]
is 'N', increment the current penalty (because if we close the shop after this hour, we add penalty).min_penalty
, update min_penalty
and earliest_hour
to i + 1
.earliest_hour
.def earliest_closing(customers):
n = len(customers)
min_penalty = float('inf')
earliest_hour = 0
penalty = 0
for c in customers:
if c == 'Y':
penalty += 1
min_penalty = penalty
for i in range(n):
if customers[i] == 'Y':
penalty -= 1
else:
penalty += 1
if penalty < min_penalty:
min_penalty = penalty
earliest_hour = i + 1
return earliest_hour