Skip to content

Commit af3d053

Browse files
authored
feat: add solutions to lc problem: No.2702 (doocs#1564)
No.2702.Minimum Operations to Make Numbers Non-positive
1 parent 7315928 commit af3d053

File tree

7 files changed

+404
-6
lines changed

7 files changed

+404
-6
lines changed

solution/2700-2799/2702.Minimum Operations to Make Numbers Non-positive/README.md

Lines changed: 144 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,34 +51,175 @@
5151

5252
<!-- 这里可写通用的实现逻辑 -->
5353

54+
**方法一:二分查找**
55+
56+
我们注意到,如果一个操作次数 $t$ 能够使得所有的数都小于等于 $0$,那么对于任意 $t' > t$,操作次数 $t'$ 也能够使得所有的数都小于等于 $0$。因此我们可以使用二分查找的方法找到最小的操作次数。
57+
58+
我们定义二分查找的左边界 $l=0$,右边界 $r=\max(nums)$。每一次二分查找,我们找到中间值 $mid=\lfloor\frac{l+r}{2}\rfloor$,然后判断是否存在一种操作方法使得操作次数不超过 $mid$,使得所有的数都小于等于 $0$。如果存在,那么我们就更新右边界 $r = mid$,否则我们就更新左边界 $l = mid + 1$。最终当 $l=r$ 时,我们就找到了最小的操作次数,返回 $l$ 即可。
59+
60+
问题的关键在于如何判断是否存在一种操作方法使得操作次数不超过 $t$,使得所有的数都小于等于 $0$。我们可以使用贪心的方法来判断是否存在这样的操作方法。
61+
62+
我们遍历数组中的每一个数 $v$,如果 $v \leq t \times y$,那么我们不需要进行任何操作。否则,我们需要的操作次数为 $\lceil\frac{v - t \times y}{x - y}\rceil$。我们将所有的操作次数相加,如果小于等于 $t$,那么就说明存在一种操作方法使得操作次数不超过 $t$,使得所有的数都小于等于 $0$。
63+
64+
时间复杂度 $O(n \times \log M)$,其中 $n$ 和 $M$ 分别是数组的长度和数组中的最大值。空间复杂度 $O(1)$。
65+
5466
<!-- tabs:start -->
5567

5668
### **Python3**
5769

5870
<!-- 这里可写当前语言的特殊实现逻辑 -->
5971

6072
```python
61-
73+
class Solution:
74+
def minOperations(self, nums: List[int], x: int, y: int) -> int:
75+
def check(t: int) -> bool:
76+
cnt = 0
77+
for v in nums:
78+
if v > t * y:
79+
cnt += ceil((v - t * y) / (x - y))
80+
return cnt <= t
81+
82+
l, r = 0, max(nums)
83+
while l < r:
84+
mid = (l + r) >> 1
85+
if check(mid):
86+
r = mid
87+
else:
88+
l = mid + 1
89+
return l
6290
```
6391

6492
### **Java**
6593

6694
<!-- 这里可写当前语言的特殊实现逻辑 -->
6795

6896
```java
69-
97+
class Solution {
98+
private int[] nums;
99+
private int x;
100+
private int y;
101+
102+
public int minOperations(int[] nums, int x, int y) {
103+
this.nums = nums;
104+
this.x = x;
105+
this.y = y;
106+
int l = 0, r = 0;
107+
for (int v : nums) {
108+
r = Math.max(r, v);
109+
}
110+
while (l < r) {
111+
int mid = (l + r) >>> 1;
112+
if (check(mid)) {
113+
r = mid;
114+
} else {
115+
l = mid + 1;
116+
}
117+
}
118+
return l;
119+
}
120+
121+
private boolean check(int t) {
122+
long cnt = 0;
123+
for (int v : nums) {
124+
if (v > (long) t * y) {
125+
cnt += (v - (long) t * y + x - y - 1) / (x - y);
126+
}
127+
}
128+
return cnt <= t;
129+
}
130+
}
70131
```
71132

72133
### **C++**
73134

74135
```cpp
75-
136+
class Solution {
137+
public:
138+
int minOperations(vector<int>& nums, int x, int y) {
139+
int l = 0, r = *max_element(nums.begin(), nums.end());
140+
auto check = [&](int t) {
141+
long long cnt = 0;
142+
for (int v : nums) {
143+
if (v > 1LL * t * y) {
144+
cnt += (v - 1LL * t * y + x - y - 1) / (x - y);
145+
}
146+
}
147+
return cnt <= t;
148+
};
149+
while (l < r) {
150+
int mid = (l + r) >> 1;
151+
if (check(mid)) {
152+
r = mid;
153+
} else {
154+
l = mid + 1;
155+
}
156+
}
157+
return l;
158+
}
159+
};
76160
```
77161
78162
### **Go**
79163
80164
```go
165+
func minOperations(nums []int, x int, y int) int {
166+
var l, r int
167+
for _, v := range nums {
168+
r = max(r, v)
169+
}
170+
check := func(t int) bool {
171+
cnt := 0
172+
for _, v := range nums {
173+
if v > t*y {
174+
cnt += (v - t*y + x - y - 1) / (x - y)
175+
}
176+
}
177+
return cnt <= t
178+
}
179+
for l < r {
180+
mid := (l + r) >> 1
181+
if check(mid) {
182+
r = mid
183+
} else {
184+
l = mid + 1
185+
}
186+
}
187+
return l
188+
}
189+
190+
func max(a, b int) int {
191+
if a > b {
192+
return a
193+
}
194+
return b
195+
}
196+
```
81197

198+
### **TypeScript**
199+
200+
```ts
201+
function minOperations(nums: number[], x: number, y: number): number {
202+
let l = 0;
203+
let r = Math.max(...nums);
204+
const check = (t: number): boolean => {
205+
let cnt = 0;
206+
for (const v of nums) {
207+
if (v > t * y) {
208+
cnt += Math.ceil((v - t * y) / (x - y));
209+
}
210+
}
211+
return cnt <= t;
212+
};
213+
while (l < r) {
214+
const mid = (l + r) >> 1;
215+
if (check(mid)) {
216+
r = mid;
217+
} else {
218+
l = mid + 1;
219+
}
220+
}
221+
return l;
222+
}
82223
```
83224

84225
### **...**

solution/2700-2799/2702.Minimum Operations to Make Numbers Non-positive/README_EN.md

Lines changed: 132 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,25 +50,154 @@ Now, all the numbers in nums are non-positive. Therefore, we return 3.
5050
### **Python3**
5151

5252
```python
53-
53+
class Solution:
54+
def minOperations(self, nums: List[int], x: int, y: int) -> int:
55+
def check(t: int) -> bool:
56+
cnt = 0
57+
for v in nums:
58+
if v > t * y:
59+
cnt += ceil((v - t * y) / (x - y))
60+
return cnt <= t
61+
62+
l, r = 0, max(nums)
63+
while l < r:
64+
mid = (l + r) >> 1
65+
if check(mid):
66+
r = mid
67+
else:
68+
l = mid + 1
69+
return l
5470
```
5571

5672
### **Java**
5773

5874
```java
59-
75+
class Solution {
76+
private int[] nums;
77+
private int x;
78+
private int y;
79+
80+
public int minOperations(int[] nums, int x, int y) {
81+
this.nums = nums;
82+
this.x = x;
83+
this.y = y;
84+
int l = 0, r = 0;
85+
for (int v : nums) {
86+
r = Math.max(r, v);
87+
}
88+
while (l < r) {
89+
int mid = (l + r) >>> 1;
90+
if (check(mid)) {
91+
r = mid;
92+
} else {
93+
l = mid + 1;
94+
}
95+
}
96+
return l;
97+
}
98+
99+
private boolean check(int t) {
100+
long cnt = 0;
101+
for (int v : nums) {
102+
if (v > (long) t * y) {
103+
cnt += (v - (long) t * y + x - y - 1) / (x - y);
104+
}
105+
}
106+
return cnt <= t;
107+
}
108+
}
60109
```
61110

62111
### **C++**
63112

64113
```cpp
65-
114+
class Solution {
115+
public:
116+
int minOperations(vector<int>& nums, int x, int y) {
117+
int l = 0, r = *max_element(nums.begin(), nums.end());
118+
auto check = [&](int t) {
119+
long long cnt = 0;
120+
for (int v : nums) {
121+
if (v > 1LL * t * y) {
122+
cnt += (v - 1LL * t * y + x - y - 1) / (x - y);
123+
}
124+
}
125+
return cnt <= t;
126+
};
127+
while (l < r) {
128+
int mid = (l + r) >> 1;
129+
if (check(mid)) {
130+
r = mid;
131+
} else {
132+
l = mid + 1;
133+
}
134+
}
135+
return l;
136+
}
137+
};
66138
```
67139
68140
### **Go**
69141
70142
```go
143+
func minOperations(nums []int, x int, y int) int {
144+
var l, r int
145+
for _, v := range nums {
146+
r = max(r, v)
147+
}
148+
check := func(t int) bool {
149+
cnt := 0
150+
for _, v := range nums {
151+
if v > t*y {
152+
cnt += (v - t*y + x - y - 1) / (x - y)
153+
}
154+
}
155+
return cnt <= t
156+
}
157+
for l < r {
158+
mid := (l + r) >> 1
159+
if check(mid) {
160+
r = mid
161+
} else {
162+
l = mid + 1
163+
}
164+
}
165+
return l
166+
}
167+
168+
func max(a, b int) int {
169+
if a > b {
170+
return a
171+
}
172+
return b
173+
}
174+
```
71175

176+
### **TypeScript**
177+
178+
```ts
179+
function minOperations(nums: number[], x: number, y: number): number {
180+
let l = 0;
181+
let r = Math.max(...nums);
182+
const check = (t: number): boolean => {
183+
let cnt = 0;
184+
for (const v of nums) {
185+
if (v > t * y) {
186+
cnt += Math.ceil((v - t * y) / (x - y));
187+
}
188+
}
189+
return cnt <= t;
190+
};
191+
while (l < r) {
192+
const mid = (l + r) >> 1;
193+
if (check(mid)) {
194+
r = mid;
195+
} else {
196+
l = mid + 1;
197+
}
198+
}
199+
return l;
200+
}
72201
```
73202

74203
### **...**
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
class Solution {
2+
public:
3+
int minOperations(vector<int>& nums, int x, int y) {
4+
int l = 0, r = *max_element(nums.begin(), nums.end());
5+
auto check = [&](int t) {
6+
long long cnt = 0;
7+
for (int v : nums) {
8+
if (v > 1LL * t * y) {
9+
cnt += (v - 1LL * t * y + x - y - 1) / (x - y);
10+
}
11+
}
12+
return cnt <= t;
13+
};
14+
while (l < r) {
15+
int mid = (l + r) >> 1;
16+
if (check(mid)) {
17+
r = mid;
18+
} else {
19+
l = mid + 1;
20+
}
21+
}
22+
return l;
23+
}
24+
};
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
func minOperations(nums []int, x int, y int) int {
2+
var l, r int
3+
for _, v := range nums {
4+
r = max(r, v)
5+
}
6+
check := func(t int) bool {
7+
cnt := 0
8+
for _, v := range nums {
9+
if v > t*y {
10+
cnt += (v - t*y + x - y - 1) / (x - y)
11+
}
12+
}
13+
return cnt <= t
14+
}
15+
for l < r {
16+
mid := (l + r) >> 1
17+
if check(mid) {
18+
r = mid
19+
} else {
20+
l = mid + 1
21+
}
22+
}
23+
return l
24+
}
25+
26+
func max(a, b int) int {
27+
if a > b {
28+
return a
29+
}
30+
return b
31+
}

0 commit comments

Comments
 (0)