花园的最大总美丽值
难度:
标签:
题目描述
代码结果
运行时间: 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)
代码细节讲解
🦆
在题解中提到的`筛选出未达标的花园`操作是基于什么条件?如何确定一个花园是否达标?
▷🦆
为什么在对未达标花园排序时选择了逆序排序,直接排序不可以吗?这样的排序顺序对策略有何影响?
▷🦆
题解中提到了`枚举可能的完善花园数`,具体是如何实现这一枚举的?这里的枚举过程有哪些关键步骤?
▷