leetcode
leetcode 1851 ~ 1900
打折购买糖果的最小开销

打折购买糖果的最小开销

难度:

标签:

题目描述

代码结果

运行时间: 23 ms, 内存: 16.1 MB


/*
 * 思路:
 * 使用Java Stream对数组进行降序排序,然后以三个一组进行处理。
 * 每组中,前两个糖果的价格累加到总开销中,第三个糖果作为免费糖果。
 */
import java.util.Arrays;
import java.util.stream.IntStream;

public class CandyStoreStream {
    public int minCost(int[] cost) {
        return IntStream.of(cost)
            .boxed()
            .sorted((a, b) -> b - a) // 按降序排序
            .collect(Collectors.toList())
            .stream()
            .collect(Collectors.chunking(3)) // 每3个为一组
            .mapToInt(chunk -> chunk.stream().limit(2).mapToInt(Integer::intValue).sum()) // 前两个累加
            .sum(); // 求和
    }

    public static void main(String[] args) {
        CandyStoreStream css = new CandyStoreStream();
        int[] cost = {6, 5, 7, 9, 2, 2};
        System.out.println(css.minCost(cost)); // 输出 23
    }
}

解释

方法:

该题解的策略是首先将糖果按价格从高到低排序,以保证在购买时能够优先获取价格较高的糖果,从而使得在每次购买两个糖果时,能够免费获得价格相对较低的糖果。具体实施中,每次循环选取三个糖果(如果存在),购买最贵的两个,并免费获得第三个。如果剩下的糖果不足三个,直接购买剩余的糖果。这样做的目的是最大化每次免费获得糖果的价值。

时间复杂度:

O(n log n)

空间复杂度:

O(1)

代码细节讲解

🦆
在解决问题的过程中,为什么选择从最高到最低的顺序对糖果进行排序,而不是从最低到最高或其他顺序?
按照价格从高到低排序的目的是在每次购买操作中最大化节省。由于规则允许每买两个糖果免费获得一个,通过优先购买最贵的糖果,可以确保每次免费获得的糖果是当前可选糖果中价格相对较低的。这种策略确保了总支付金额最小化,因为它减少了高价值糖果的支付次数,并最大化了低价值糖果的免费获得次数。
🦆
该算法在处理剩下两个糖果时是否考虑了选择哪两个糖果购买以最大化免费获得的糖果价值?
在剩下两个糖果的情况下,算法并没有涉及选择问题,因为只有两个糖果可供选择,所以必须购买这两个糖果,没有免费获得的糖果。这种情况下,策略简单地涉及支付这两个糖果的总价,而没有进一步的优化空间。
🦆
在每次循环中跳过第三个糖果作为免费糖果的决策是否总是最优,存在没有更好的选择吗?
在这个策略中,选择最贵的两个糖果并跳过第三个作为免费糖果是最优的决策。这样做是因为我们希望支付最贵的糖果,从而最大化免费获得的糖果的价值。如果选择较便宜的糖果作为付费糖果,那么免费获得的糖果平均价格会更高,从而增加总花费。因此,在这种情况下,没有更好的选择。
🦆
如果数组长度不是3的倍数,剩下的一到两个糖果的处理逻辑是否足够高效?
如果数组长度不是3的倍数,处理剩下的一到两个糖果的逻辑是直接购买这些糖果,因为没有足够的糖果来组成一个完整的买二送一的组合。这种处理方式是高效的,因为它简单且直接,确保了所有糖果都被考虑到,同时避免了复杂的额外逻辑或不必要的计算。

相关问题