You are given a 0-indexed integer array nums and two integers x and
y. In one operation, you must choose an index i such that 0 <= i < nums.length and perform the following:
Decrement nums[i] by x.
Decrement values by y at all indices except the ith one.
Return the minimum number of operations to make all the integers innumsless than or equal to zero.
Input: nums =[3,4,1,7,6], x =4, y =2Output: 3Explanation: You will need three operations. One of the optimal sequence of operations is:Operation 1: Choose i =3. Then, nums =[1,2,-1,3,4].Operation 2: Choose i =3. Then, nums =[-1,0,-3,-1,2].Operation 3: Choose i =4. Then, nums =[-3,-2,-5,-3,-2].Now, all the numbers in nums are non-positive. Therefore, we return3.
Example 2:
1
2
3
Input: nums =[1,2,1], x =2, y =1Output: 1Explanation: We can perform the operation once on i =1. Then, nums becomes [0,0,0]. All the positive numbers are removed, and therefore, we return1.
Each operation reduces one element by x and all others by y. The optimal strategy is to perform the operation on the largest element, as it benefits most from the larger decrement. We can use binary search to find the minimum number of operations needed so that all elements become non-positive.
classSolution {
public:int minOperations(vector<int>& nums, int x, int y) {
int n = nums.size();
int l =0, r =*max_element(nums.begin(), nums.end()) / y +2;
auto check = [&](int ops) {
longlong need =0;
for (int v : nums) {
longlong left = v -1LL* ops * y;
if (left >0) need += (left + (x - y -1)) / (x - y);
}
return need <= ops;
};
while (l < r) {
int m = (l + r) /2;
if (check(m)) r = m;
else l = m +1;
}
return l;
}
};
funcminOperations(nums []int, x, yint) int {
l, r:=0, 0for_, v:=rangenums {
ifv/y+2 > r { r = v/y+2 }
}
check:=func(opsint) bool {
need:=0for_, v:=rangenums {
left:=v-ops*yifleft > 0 {
need+= (left+ (x-y-1)) / (x-y)
}
}
returnneed<=ops }
forl < r {
m:= (l+r) /2ifcheck(m) {
r = m } else {
l = m+1 }
}
returnl}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
classSolution {
publicintminOperations(int[] nums, int x, int y) {
int l = 0, r = 0;
for (int v : nums) r = Math.max(r, v / y + 2);
while (l < r) {
int m = (l + r) / 2;
long need = 0;
for (int v : nums) {
long left = v - 1L * m * y;
if (left > 0) need += (left + (x - y - 1)) / (x - y);
}
if (need <= m) r = m;
else l = m + 1;
}
return l;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
classSolution {
funminOperations(nums: IntArray, x: Int, y: Int): Int {
var l = 0var r = nums.maxOrNull()!! / y + 2while (l < r) {
val m = (l + r) / 2var need = 0Lfor (v in nums) {
val left = v - m * y
if (left > 0) need += (left + (x - y - 1)) / (x - y)
}
if (need <= m) r = m else l = m + 1 }
return l
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
classSolution:
defminOperations(self, nums: list[int], x: int, y: int) -> int:
l, r =0, max(nums) // y +2while l < r:
m = (l + r) //2 need =0for v in nums:
left = v - m * y
if left >0:
need += (left + (x - y -1)) // (x - y)
if need <= m:
r = m
else:
l = m +1return l
impl Solution {
pubfnmin_operations(nums: Vec<i32>, x: i32, y: i32) -> i32 {
letmut l =0;
letmut r = nums.iter().max().unwrap() / y +2;
while l < r {
let m = (l + r) /2;
letmut need =0;
for&v in&nums {
let left = v - m * y;
if left >0 {
need += (left + (x - y -1)) / (x - y);
}
}
if need <= m {
r = m;
} else {
l = m +1;
}
}
l
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
classSolution {
minOperations(nums: number[], x: number, y: number):number {
letl=0, r= Math.max(...nums) /y+2;
while (l<r) {
constm= Math.floor((l+r) /2);
letneed=0;
for (constvofnums) {
constleft=v-m*y;
if (left>0) need+= Math.floor((left+ (x-y-1)) / (x-y));
}
if (need<=m) r=m;
elsel=m+1;
}
returnl;
}
}