2483: 商店的最少代价
把 customers 分成两段,第一段计算 N 的个数 preN,第二段计算 Y 的个数 sufY。
注:也可以不分割,相当于其中一段是空的。
思路:先假设所有字母都在第二段(关门),统计 customers 中 Y 的个数 sufY。想象一根分割线在从左到右移动,customers[i] 原来在第二段,现在在第一段。如果 customers[i]=N,那么把 preN 加一(preN 初始值为 0),否则把 sufY 减一。答案为 preN+sufY 最小时对应的分割位置。
代码实现时,preN+sufY 可以合并为一个变量 penalty。
class Solution {
public:
int bestClosingTime(string customers) {
int penalty = ranges::count(customers, 'Y');
int min_penalty = penalty;
int ans = 0; // [0,n-1] 是第二段
for (int i = 0; i < customers.size(); i++) {
penalty += customers[i] == 'N' ? 1 : -1;
if (penalty < min_penalty) {
min_penalty = penalty;
ans = i + 1; // [0,i] 是第一段,[i+1,n-1] 是第二段
}
}
return ans;
}
};