题目地址:
https://leetcode.com/problems/minimum-operations-to-make-numbers-non-positive/description/
给定一个长 n n n正整数数组 a a a,再给定两个正整数 x x x和 y y y并且 x > y x>y x>y。每一次操作允许将某个位置的数减 x x x,并将所有其他数减 y y y。问至少多少次操作可以使得整个数组每个数都非正。
可以二分答案。我们验证 p p p次操作是否能达到目的。我们可以将一次操作理解为,先将所有数都减去 y y y,同时再挑一个数减去 x − y x-y x−y。那么 p p p次操作就可以理解为,每个数先减去 p y py py,然后还有 p p p次机会再将一些数减 x − y x-y x−y。我们只需要验证哪些数需要额外的机会,并且总的额外的机会个数是否小于等于 p p p即可。代码如下:
class Solution {
public:
using ll = long long;
int minOperations(vector<int>& a, int x, int y) {
int l = 1, r = 0;
for (int x : a) r = max(r, x);
r = (r + y - 1) / y;
int diff = x - y;
auto f = [&](int op) {
ll extra_op = 0;
for (int z : a) {
int r = z - y * op;
// r > 0说明当前数z需要额外机会
if (r > 0) extra_op += ((ll)r + diff - 1) / diff;
}
return extra_op <= op;
};
while (l < r) {
int mid = l + (r - l >> 1);
if (f(mid))
r = mid;
else
l = mid + 1;
}
return l;
}
};
时间复杂度 O ( n log max a y ) O(n\log \frac{\max a}{y}) O(nlogymaxa),空间 O ( 1 ) O(1) O(1)。