classSolution: defmaxPower(self, stations: List[int], r: int, k: int) -> int: n = len(stations) sum = list(accumulate(stations, initial=0)) # 前缀和 for i inrange(n): stations[i] = sum[min(i + r + 1, n)] - sum[max(i - r, 0)] # 电量
defcheck(min_power: int) -> bool: diff = [0] * n # 差分数组 sum_d = need = 0 for i, power inenumerate(stations): sum_d += diff[i] # 累加差分值 m = min_power - power - sum_d if m > 0: # 需要 m 个供电站 need += m if need > k: returnFalse# 提前退出这样快一些 sum_d += m # 差分更新 if i + r * 2 + 1 < n: diff[i + r * 2 + 1] -= m # 差分更新 returnTrue
left = min(stations) right = left + k + 1# 开区间写法 while left + 1 < right: mid = (left + right) // 2 if check(mid): left = mid else: right = mid return left
classSolution { public: longlongmaxPower(vector<int> &stations, int r, int k){ int n = stations.size(); long sum[n + 1], power[n], diff[n]; sum[0] = 0; for (int i = 0; i < n; ++i) sum[i + 1] = sum[i] + stations[i]; // 前缀和 for (int i = 0; i < n; ++i) power[i] = sum[min(i + r + 1, n)] - sum[max(i - r, 0)]; // 电量
auto check = [&](long min_power) -> bool { memset(diff, 0, sizeof(diff)); // 重置差分数组 long sum_d = 0, need = 0; for (int i = 0; i < n; ++i) { sum_d += diff[i]; // 累加差分值 long m = min_power - power[i] - sum_d; if (m > 0) { // 需要 m 个供电站 need += m; if (need > k) returnfalse; // 提前退出这样快一些 sum_d += m; // 差分更新 if (i + r * 2 + 1 < n) diff[i + r * 2 + 1] -= m; // 差分更新 } } returntrue; };
long left = *min_element(power, power + n), right = left + k + 1; // 开区间写法 while (left + 1 < right) { long mid = left + (right - left) / 2; check(mid) ? left = mid : right = mid; } return left; } };
funcmaxPower(stations []int, r int, k int)int64 { n := len(stations) sum := make([]int, n+1) // 前缀和 for i, x := range stations { sum[i+1] = sum[i] + x } mn := math.MaxInt for i := range stations { stations[i] = sum[min(i+r+1, n)] - sum[max(i-r, 0)] // 电量 mn = min(mn, stations[i]) } returnint64(mn + sort.Search(k, func(minPower int)bool { minPower += mn + 1// 改为二分最小的不满足要求的值,这样 sort.Search 返回的就是最大的满足要求的值 diff := make([]int, n) // 差分数组 sumD, need := 0, 0 for i, power := range stations { sumD += diff[i] // 累加差分值 m := minPower - power - sumD if m > 0 { // 需要 m 个供电站 need += m if need > k { // 提前退出这样快一些 returntrue// 不满足要求 } sumD += m // 差分更新 if i+r*2+1 < n { diff[i+r*2+1] -= m // 差分更新 } } } returnfalse })) }
funcmin(a, b int)int { if b < a { return b }; return a } funcmax(a, b int)int { if b > a { return b }; return a }
复杂度分析
时间复杂度:O(n\log k),其中 n 为 stations 的长度。二分需要循环 O(\log k) 次。