原文链接: https://leetcode-cn.com/problems/apply-discount-every-n-orders
英文原文
There is a supermarket that is frequented by many customers. The products sold at the supermarket are represented as two parallel integer arrays products
and prices
, where the ith
product has an ID of products[i]
and a price of prices[i]
.
When a customer is paying, their bill is represented as two parallel integer arrays product
and amount
, where the jth
product they purchased has an ID of product[j]
, and amount[j]
is how much of the product they bought. Their subtotal is calculated as the sum of each amount[j] * (price of the jth product)
.
The supermarket decided to have a sale. Every nth
customer paying for their groceries will be given a percentage discount. The discount amount is given by discount
, where they will be given discount
percent off their subtotal. More formally, if their subtotal is bill
, then they would actually pay bill * ((100 - discount) / 100)
.
Implement the Cashier
class:
Cashier(int n, int discount, int[] products, int[] prices)
Initializes the object withn
, thediscount
, and theproducts
and theirprices
.double getBill(int[] product, int[] amount)
Returns the final total of the bill with the discount applied (if any). Answers within10-5
of the actual value will be accepted.
Example 1:
Input ["Cashier","getBill","getBill","getBill","getBill","getBill","getBill","getBill"] [[3,50,[1,2,3,4,5,6,7],[100,200,300,400,300,200,100]],[[1,2],[1,2]],[[3,7],[10,10]],[[1,2,3,4,5,6,7],[1,1,1,1,1,1,1]],[[4],[10]],[[7,3],[10,10]],[[7,5,3,1,6,4,2],[10,10,10,9,9,9,7]],[[2,3,5],[5,3,2]]] Output [null,500.0,4000.0,800.0,4000.0,4000.0,7350.0,2500.0] Explanation Cashier cashier = new Cashier(3,50,[1,2,3,4,5,6,7],[100,200,300,400,300,200,100]); cashier.getBill([1,2],[1,2]); // return 500.0. 1st customer, no discount. // bill = 1 * 100 + 2 * 200 = 500. cashier.getBill([3,7],[10,10]); // return 4000.0. 2nd customer, no discount. // bill = 10 * 300 + 10 * 100 = 4000. cashier.getBill([1,2,3,4,5,6,7],[1,1,1,1,1,1,1]); // return 800.0. 3rd customer, 50% discount. // Original bill = 1600 // Actual bill = 1600 * ((100 - 50) / 100) = 800. cashier.getBill([4],[10]); // return 4000.0. 4th customer, no discount. cashier.getBill([7,3],[10,10]); // return 4000.0. 5th customer, no discount. cashier.getBill([7,5,3,1,6,4,2],[10,10,10,9,9,9,7]); // return 7350.0. 6th customer, 50% discount. // Original bill = 14700, but with // Actual bill = 14700 * ((100 - 50) / 100) = 7350. cashier.getBill([2,3,5],[5,3,2]); // return 2500.0. 6th customer, no discount.
Constraints:
1 <= n <= 104
0 <= discount <= 100
1 <= products.length <= 200
prices.length == products.length
1 <= products[i] <= 200
1 <= prices[i] <= 1000
- The elements in
products
are unique. 1 <= product.length <= products.length
amount.length == product.length
product[j]
exists inproducts
.1 <= amount[j] <= 1000
- The elements of
product
are unique. - At most
1000
calls will be made togetBill
. - Answers within
10-5
of the actual value will be accepted.
中文题目
超市里正在举行打折活动,每隔 n
个顾客会得到 discount
的折扣。
超市里有一些商品,第 i
种商品为 products[i]
且每件单品的价格为 prices[i]
。
结账系统会统计顾客的数目,每隔 n
个顾客结账时,该顾客的账单都会打折,折扣为 discount
(也就是如果原本账单为 x
,那么实际金额会变成 x - (discount * x) / 100
),然后系统会重新开始计数。
顾客会购买一些商品, product[i]
是顾客购买的第 i
种商品, amount[i]
是对应的购买该种商品的数目。
请你实现 Cashier
类:
Cashier(int n, int discount, int[] products, int[] prices)
初始化实例对象,参数分别为打折频率n
,折扣大小discount
,超市里的商品列表products
和它们的价格prices
。double getBill(int[] product, int[] amount)
返回账单的实际金额(如果有打折,请返回打折后的结果)。返回结果与标准答案误差在10^-5
以内都视为正确结果。
示例 1:
输入 ["Cashier","getBill","getBill","getBill","getBill","getBill","getBill","getBill"] [[3,50,[1,2,3,4,5,6,7],[100,200,300,400,300,200,100]],[[1,2],[1,2]],[[3,7],[10,10]],[[1,2,3,4,5,6,7],[1,1,1,1,1,1,1]],[[4],[10]],[[7,3],[10,10]],[[7,5,3,1,6,4,2],[10,10,10,9,9,9,7]],[[2,3,5],[5,3,2]]] 输出 [null,500.0,4000.0,800.0,4000.0,4000.0,7350.0,2500.0] 解释 Cashier cashier = new Cashier(3,50,[1,2,3,4,5,6,7],[100,200,300,400,300,200,100]); cashier.getBill([1,2],[1,2]); // 返回 500.0, 账单金额为 = 1 * 100 + 2 * 200 = 500. cashier.getBill([3,7],[10,10]); // 返回 4000.0 cashier.getBill([1,2,3,4,5,6,7],[1,1,1,1,1,1,1]); // 返回 800.0 ,账单原本为 1600.0 ,但由于该顾客是第三位顾客,他将得到 50% 的折扣,所以实际金额为 1600 - 1600 * (50 / 100) = 800 。 cashier.getBill([4],[10]); // 返回 4000.0 cashier.getBill([7,3],[10,10]); // 返回 4000.0 cashier.getBill([7,5,3,1,6,4,2],[10,10,10,9,9,9,7]); // 返回 7350.0 ,账单原本为 14700.0 ,但由于系统计数再次达到三,该顾客将得到 50% 的折扣,实际金额为 7350.0 。 cashier.getBill([2,3,5],[5,3,2]); // 返回 2500.0
提示:
1 <= n <= 10^4
0 <= discount <= 100
1 <= products.length <= 200
1 <= products[i] <= 200
products
列表中 不会 有重复的元素。prices.length == products.length
1 <= prices[i] <= 1000
1 <= product.length <= products.length
product[i]
在products
出现过。amount.length == product.length
1 <= amount[i] <= 1000
- 最多有
1000
次对getBill
函数的调用。 - 返回结果与标准答案误差在
10^-5
以内都视为正确结果。
通过代码
高赞题解
方法一:模拟
我们将所有的物品以及它们的价格存放进哈希映射(HashMap)中。对于哈希映射中的每个键值对,键表示物品的编号,值表示物品的价格,这样我们就可以方便快速地统计每一位顾客的消费金额了。
为了判断每一位顾客是否可以得到折扣,我们还需要使用一个计数器表示当前顾客的序号,如果该序号是 n
的倍数,我们就按照 discount
对顾客的消费金额进行打折。
class Cashier {
private:
unordered_map<int, int> price;
int n, discount;
int custom_id;
public:
Cashier(int _n, int _d, vector<int>& products, vector<int>& prices): n(_n), discount(_d), custom_id(0) {
for (int i = 0; i < products.size(); ++i) {
price[products[i]] = prices[i];
}
}
double getBill(vector<int> product, vector<int> amount) {
++custom_id;
double payment = 0;
for (int i = 0; i < product.size(); ++i) {
payment += price[product[i]] * amount[i];
}
if (custom_id % n == 0) {
payment -= payment * discount / 100;
}
return payment;
}
};
class Cashier:
def __init__(self, n: int, discount: int, products: List[int], prices: List[int]):
self.price = dict()
for product, price in zip(products, prices):
self.price[product] = price
self.n = n
self.discount = discount
self.custom_id = 0
def getBill(self, product: List[int], amount: List[int]) -> float:
self.custom_id += 1
payment = 0.0
for k, v in zip(product, amount):
payment += self.price[k] * v
if self.custom_id % self.n == 0:
payment -= payment * self.discount / 100
return payment
复杂度分析
时间复杂度:预处理(Cashier 类的构造函数)的时间复杂度为 $O(P)$,其中 $P$ 是数组
products
和prices
的长度。getBill()
的时间复杂度为 $O(M)$,其中 $M$ 是数组product
和amount
的长度。空间复杂度:预处理的空间复杂度为 $O(P)$。
getBill()
的额外(预处理的结果之外)空间复杂度为 $O(1)$。
统计信息
通过次数 | 提交次数 | AC比率 |
---|---|---|
4378 | 8216 | 53.3% |
提交历史
提交时间 | 提交结果 | 执行时间 | 内存消耗 | 语言 |
---|