leetcode
leetcode 2151 ~ 2200
商店的最少代价

商店的最少代价

难度:

标签:

题目描述

You are given the customer visit log of a shop represented by a 0-indexed string customers consisting only of characters 'N' and 'Y':

  • if the ith character is 'Y', it means that customers come at the ith hour
  • whereas 'N' indicates that no customers come at the ith hour.

If the shop closes at the jth hour (0 <= j <= n), the penalty is calculated as follows:

  • For every hour when the shop is open and no customers come, the penalty increases by 1.
  • For every hour when the shop is closed and customers come, the penalty increases by 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 jth hour, it means the shop is closed at the hour j.

 

Example 1:

Input: customers = "YYNY"
Output: 2
Explanation: 
- Closing the shop at the 0th hour incurs in 1+1+0+1 = 3 penalty.
- Closing the shop at the 1st hour incurs in 0+1+0+1 = 2 penalty.
- Closing the shop at the 2nd hour incurs in 0+0+0+1 = 1 penalty.
- Closing the shop at the 3rd hour incurs in 0+0+1+1 = 2 penalty.
- Closing the shop at the 4th hour incurs in 0+0+1+0 = 1 penalty.
Closing the shop at 2nd or 4th hour gives a minimum penalty. Since 2 is earlier, the optimal closing time is 2.

Example 2:

Input: customers = "NNNNN"
Output: 0
Explanation: It is best to close the shop at the 0th hour as no customers arrive.

Example 3:

Input: customers = "YYYY"
Output: 4
Explanation: It is best to close the shop at the 4th hour as customers arrive at each hour.

 

Constraints:

  • 1 <= customers.length <= 105
  • customers consists only of characters 'Y' and 'N'.

代码结果

运行时间: 68 ms, 内存: 17.0 MB


/*
 * Problem Statement:
 * You are given a log of customers visiting a store as a string containing only 'N' and 'Y' characters.
 * 'Y' indicates a customer arrived during that hour, and 'N' indicates no customer arrived.
 * Calculate the minimum cost for closing the store at any hour from 0 to n (inclusive), where
 * closing at hour j means the store is closed during and after the jth hour.
 * Cost is calculated as:
 * 1. For each 'N' during opening hours, the cost increases by 1.
 * 2. For each 'Y' during closing hours, the cost increases by 1.
 * Return the earliest hour j that minimizes the cost.
 */
import java.util.stream.IntStream;

public class Solution {
    public int bestClosingTime(String customers) {
        int n = customers.length();
        int[] prefixNoCustomers = new int[n + 1];
        int[] suffixCustomers = new int[n + 1];

        // Calculate prefix costs (no customers during open hours)
        IntStream.range(0, n).forEach(i -> prefixNoCustomers[i + 1] = prefixNoCustomers[i] + (customers.charAt(i) == 'N' ? 1 : 0));

        // Calculate suffix costs (customers during closed hours)
        IntStream.range(0, n).map(i -> n - 1 - i).forEach(i -> suffixCustomers[i] = suffixCustomers[i + 1] + (customers.charAt(i) == 'Y' ? 1 : 0));

        // Find the minimum cost and the earliest closing time
        return IntStream.rangeClosed(0, n).reduce((bestTime, j) -> 
            prefixNoCustomers[j] + suffixCustomers[j] < prefixNoCustomers[bestTime] + suffixCustomers[bestTime] ? j : bestTime
        ).orElse(0);
    }
}

解释

方法:

题解的思路是遍历一次字符串customers,使用一个cost变量来跟踪开门期间没有顾客('N')和关门期间有顾客到达('Y')的代价。每次遇到'N',代价加1;遇到'Y',代价减1。如果cost变为负值,这意味着到目前为止如果一直开门,将没有额外代价。因此,将ans更新为当前小时数,并将cost重置为0。最终返回的ans是最早的时间点,使得之后关门的代价最小。

时间复杂度:

O(n)

空间复杂度:

O(1)

代码细节讲解

🦆
在算法中,为什么每遇到'N'字符时代价增加1,而每遇到'Y'字符时代价减少1,这种处理方式的合理性是什么?
这种处理方式的合理性在于代价(cost)代表了保持门开的总成本。当'N'出现时,即没有顾客到访,若门是开的则产生了不必要的成本,因此代价增加1。相反,当'Y'出现时,表示有顾客到访,如果此时门是开的,这是必要的,因此相对于关门状态来说,开门是节省了成本,故代价减少1。这种计算方式反映了保持门开状态的经济效益或损失。
🦆
算法中提到如果cost变成负值就更新ans并重置cost为0,这样处理的直觉和逻辑依据是什么?
当cost变成负值时,这意味着从开始到当前时间点开门的总代价是负的,即开门比关门更省成本,因此这个时间点之前开门是合算的。更新ans为当前时间点,是因为这可能是关门成本最小化的最佳时间。重置cost为0是为了重新计算从这个时间点开始到后面的代价,以便找到可能存在的下一个更优的关门时间。
🦆
为什么选择从索引1开始遍历customers字符串,这样的处理对最终结果有什么影响?
从索引1开始遍历customers字符串是为了使每个索引直接对应于小时数,便于理解和实现。这样处理使得在更新最佳关闭时间ans时直接使用索引值,无需额外的转换或调整,从而简化了代码实现。对最终结果的影响是确保ans精确地反映了小时数,而不是数组的下标。
🦆
代码中是否应该处理customers为空字符串的情况?
是的,应该处理customers为空字符串的情况。在当前代码实现中,如果customers为空字符串,则不进入循环,直接返回ans的初始值0。但在实际应用中,这可能不是期望的行为,因为没有顾客数据时可能更合适的返回值是一个表示无效或不适用的特殊值,例如-1或null,来明确表示没有合适的关闭时间。

相关问题