leetcode
leetcode 1951 ~ 2000
花园的最大总美丽值

花园的最大总美丽值

难度:

标签:

题目描述

代码结果

运行时间: 192 ms, 内存: 27.8 MB


/*
题目思路:
1. 对flowers数组排序,计算出使每个花园达到target所需的额外花数。
2. 使用滑动窗口或双指针的方法计算能够种满的花园数目,以及剩余不完善花园中的最小花数。
3. 计算并更新最大总美丽值。
*/
import java.util.*;
import java.util.stream.*;

public class Solution {
    public long maximumBeauty(int[] flowers, int newFlowers, int target, int full, int partial) {
        Arrays.sort(flowers);
        int n = flowers.length;
        long[] prefixSum = new long[n + 1];
        IntStream.range(1, n + 1).forEach(i -> prefixSum[i] = prefixSum[i - 1] + flowers[i - 1]);
        return IntStream.rangeClosed(0, n).mapToLong(i -> {
            if (i > 0 && flowers[i - 1] >= target) return 0;
            int remainingFlowers = newFlowers - (target * i - (prefixSum[n] - prefixSum[n - i]));
            if (remainingFlowers < 0) return 0;
            int left = 0, right = target - 1, minPartial = 0;
            while (left <= right) {
                int mid = (left + right) / 2;
                int pos = Arrays.binarySearch(flowers, 0, n - i, mid);
                if (pos < 0) pos = -pos - 1;
                long needed = (long) mid * pos - prefixSum[pos];
                if (needed <= remainingFlowers) {
                    minPartial = mid;
                    left = mid + 1;
                } else {
                    right = mid - 1;
                }
            }
            return (long) full * i + (long) partial * minPartial;
        }).max().orElse(0);
    }
}

解释

方法:

这个问题的解法涉及到排序和贪心策略。首先,我们将所有已经达到或超过目标花朵数的花园筛选出来,这些花园已经是'完善的'。对于剩余的花园,我们将其排序并尝试通过添加花朵来使得更多的花园成为'完善的'。我们从没有达到目标的花园列表中,从最需要花朵最少的开始,尝试通过增加花朵使其达到或超过目标花朵数。通过枚举可能的完善花园数,我们可以计算出每种情况下的美丽值,并更新最大值。关键点在于动态地调整剩余花朵的分配,以及如何计算在某种分配下的最小不完善花园中的花朵数。

时间复杂度:

O(n log n) + O(n^2) = O(n^2)

空间复杂度:

O(n)

代码细节讲解

🦆
在题解中提到的`筛选出未达标的花园`操作是基于什么条件?如何确定一个花园是否达标?
在题解中,`筛选出未达标的花园`是基于花园当前的花朵数是否达到了设定的目标花朵数`target`。如果一个花园的花朵数量小于`target`,则这个花园被认为是未达标的。这样的筛选是为了将注意力集中在那些需要额外添加花朵以达标的花园上,从而优化花朵的分配和使用策略。
🦆
为什么在对未达标花园排序时选择了逆序排序,直接排序不可以吗?这样的排序顺序对策略有何影响?
在题解中选择逆序排序(从大到小排序)是为了优化花朵的分配过程。通过先处理那些离达标差距较小的花园,可以更高效地使用新增的花朵。逆序排序确保了在每一步尝试完善花园时,我们都尽可能地接近目标,从而可能减少需要的总花朵数。如果采用正序排序,则可能导致在处理花朵需求较大的花园时,已经没有足够的花朵来满足需求,从而影响总体的策略效率。
🦆
题解中提到了`枚举可能的完善花园数`,具体是如何实现这一枚举的?这里的枚举过程有哪些关键步骤?
题解中实现`枚举可能的完善花园数`的方法是逐一尝试每个可能的花园数量,并计算在这种情况下的最大美丽值。关键步骤包括:1. 从0开始,逐个增加完善的花园数量,同时递减剩余可用的花朵数。2. 更新剩余花朵数后,检查是否有足够的花朵来继续增加完善的花园数量。3. 调整索引`j`,确保剩余的花朵数足以至少保持当前的完善花园数。4. 计算在当前完善花园数下,最小的不完善花园可以达到的花朵数,并据此更新可能的最大美丽值。这种枚举和调整的过程允许动态地评估不同完善花园数量下的美丽值,找到最优解。

相关问题