力扣题解(大礼包)
638. 大礼包
已解答
中等
相关标签
相关企业
在 LeetCode 商店中, 有 n
件在售的物品。每件物品都有对应的价格。然而,也有一些大礼包,每个大礼包以优惠的价格捆绑销售一组物品。
给你一个整数数组 price
表示物品价格,其中 price[i]
是第 i
件物品的价格。另有一个整数数组 needs
表示购物清单,其中 needs[i]
是需要购买第 i
件物品的数量。
还有一个数组 special
表示大礼包,special[i]
的长度为 n + 1
,其中 special[i][j]
表示第 i
个大礼包中内含第 j
件物品的数量,且 special[i][n]
(也就是数组中的最后一个整数)为第 i
个大礼包的价格。
返回 确切 满足购物清单所需花费的最低价格,你可以充分利用大礼包的优惠活动。你不能购买超出购物清单指定数量的物品,即使那样会降低整体价格。任意大礼包可无限次购买。
思路:
本题可以发现物品数目极少,最多只有6种,且每种物品需要的数量不超过10种,即所有可能是11的6次方,因此遍历所有情况不会超过10的7次方的范围,不会超时。
具体遍历方式:对于当前的需求curneed,先考虑全部用单买的方式得出一个价格,然后对所有礼包进行遍历,如果当前礼包买完以后,剩下需要的物品数目不会有负数,那么表示当前买这个礼包是合法的(因为本题要求精确的买每一个需要的物品,数量不能超过所需要的数量),那就用同样的方式,找到去掉这个礼包之后的需求的最大值money,用money加上礼包的价格,和当前需求的最小花费比较,得出更小的当前最小花费,最后返回题目要求的nee的的最小花费就是结果。
优化:本题中有些礼包可能会不划算,即买礼包比单买同样数目的物品所需要的价值还要高,那这个礼包一定是不需要的。另外有些礼包可能没有任何物品,或者礼包里的物品数目本来就超过了所需要的数目,那这些礼包一定是不用考虑的,可以直接舍弃。
另外可以用记忆化搜索的方式保存当前curneed的最小花费,减少重复运算的次数。
时间复杂度分析:
假设礼包是M个,物品是n个,每个物品需要的数目不超过N。
对于礼包优化,所需要的时间是n*m,对于函数,一共有最多N的n次方种情况,每种情况需要n的时间去遍历单买,M*n的时间去遍历礼包,因此极限情况下是M*n*N的n次方,空间复杂度是N的n次方存状态和递归,M存优化后的礼包,是N的n次方+M的空间。