leetcode
leetcode 2201 ~ 2250
最大化城市的最小电量

最大化城市的最小电量

难度:

标签:

题目描述

You are given a 0-indexed integer array stations of length n, where stations[i] represents the number of power stations in the ith city.

Each power station can provide power to every city in a fixed range. In other words, if the range is denoted by r, then a power station at city i can provide power to all cities j such that |i - j| <= r and 0 <= i, j <= n - 1.

  • Note that |x| denotes absolute value. For example, |7 - 5| = 2 and |3 - 10| = 7.

The power of a city is the total number of power stations it is being provided power from.

The government has sanctioned building k more power stations, each of which can be built in any city, and have the same range as the pre-existing ones.

Given the two integers r and k, return the maximum possible minimum power of a city, if the additional power stations are built optimally.

Note that you can build the k power stations in multiple cities.

 

Example 1:

Input: stations = [1,2,4,5,0], r = 1, k = 2
Output: 5
Explanation: 
One of the optimal ways is to install both the power stations at city 1. 
So stations will become [1,4,4,5,0].
- City 0 is provided by 1 + 4 = 5 power stations.
- City 1 is provided by 1 + 4 + 4 = 9 power stations.
- City 2 is provided by 4 + 4 + 5 = 13 power stations.
- City 3 is provided by 5 + 4 = 9 power stations.
- City 4 is provided by 5 + 0 = 5 power stations.
So the minimum power of a city is 5.
Since it is not possible to obtain a larger power, we return 5.

Example 2:

Input: stations = [4,4,4,4], r = 0, k = 3
Output: 4
Explanation: 
It can be proved that we cannot make the minimum power of a city greater than 4.

 

Constraints:

  • n == stations.length
  • 1 <= n <= 105
  • 0 <= stations[i] <= 105
  • 0 <= r <= n - 1
  • 0 <= k <= 109

代码结果

运行时间: 864 ms, 内存: 29.1 MB


/*
题目思路:
1. 使用 Java Stream API 实现题解。
2. 通过将数组转换为流进行处理。
3. 计算每个城市在给定范围内的电量。
4. 使用二分搜索找到最小的最大电量。
*/
import java.util.Arrays;
import java.util.stream.IntStream;
public class Solution {
    public int maxPower(int[] stations, int r, int k) {
        int n = stations.length;
        long left = 0, right = (long) 1e18;
        while (left < right) {
            long mid = (left + right) / 2;
            if (canAchieve(stations, r, k, mid)) {
                right = mid;
            } else {
                left = mid + 1;
            }
        }
        return (int) left;
    }
    private boolean canAchieve(int[] stations, int r, int k, long target) {
        int n = stations.length;
        long[] power = Arrays.stream(stations).mapToLong(i -> i).toArray();
        long additional = 0;
        for (int i = 0; i < n; i++) {
            if (i > 0) power[i] += power[i - 1];
            if (i >= 2 * r + 1) power[i] -= stations[i - 2 * r - 1];
            if (power[i] < target) {
                long add = target - power[i];
                additional += add;
                if (additional > k) return false;
                power[i] += add;
                if (i + r + 1 < n) stations[i + r + 1] += add;
            }
        }
        return true;
    }
}

解释

方法:

题解采用了二分查找和差分数组的组合技术来解决问题。首先,根据电站的覆盖范围 r,初始化一个前缀和数组 pre,用于计算每个城市的初始供电情况。如果 r 覆盖整个数组,则简单地将 k 加到所有电站数之和上。否则,使用滑动窗口计算每个城市由覆盖范围内的电站提供的电力总和。接下来,使用二分搜索尝试找到可能的最小电量的最大值。对于二分搜索中的每个中间值 mid,使用差分数组来模拟在不同位置增加 k 个电站后的电力分布,以检查是否所有城市的电量都可以达到 mid。最终通过调整二分搜索的上下界,找到最大的可行电量。

时间复杂度:

O(n log(maxPower))

空间复杂度:

O(n)

代码细节讲解

🦆
题解中提到使用二分搜索来确定最小电量的最大值,为何选择二分搜索作为这个问题的解决方案?
二分搜索被选择用于解决此问题,因为我们需要在可能的电量值范围内找到一个最大值,使得所有城市的电量都不低于这个值。这是一个典型的“决策问题”,我们需要判断一个电量值是否能满足条件。通过不断地调整电量值范围来逼近最大可能的电量值,二分搜索能有效地在有序的数据范围中快速缩小搜索区间,从而找到最优解。
🦆
在题解的差分数组部分,如何确保增加的电站数不会超过k,特别是在处理边界位置时?
在使用差分数组进行模拟时,算法会逐一检查每个城市当前的电量是否低于目标中值(mid)。如果某个城市的电量不足,算法计算出必须增加的电站数,并累加到总增加的电站数(cnt)中。每当增加电站时,都会检查累加后的总电站数是否超过了k。如果超过k,则函数返回False,表示当前的中值不可行。这样,通过在增加电站数时持续监控总数,我们确保不会超出k的限制。同时,差分数组的更新确保了增加的电站影响可以正确地延伸到适当的范围内,而不会错误地扩展到数组外。
🦆
详述如何使用差分数组模拟在不同位置增加电站后的电力分布?
差分数组是一种用于表示数值序列中相邻元素差值的技术,可以高效地处理区间增减值的问题。在本题中,当发现某个城市的电量低于目标值时,我们不仅需要在当前位置增加必要的电站,还需要确保这种增加影响可以覆盖到电站的最大范围(即2r)。通过在当前位置增加电站数,并在超出电站范围的下一个位置减去相同的电站数,差分数组能够有效地模拟每个城市实际受到的电站影响。随后,通过累加差分数组来得到每个城市实际的电站数,这种方法使得多次更新操作的复杂度仍然保持在线性级别。

相关问题