Skip to content

feat: add solutions to lc problem: No.1760 #4053

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
148 changes: 97 additions & 51 deletions solution/1700-1799/1760.Minimum Limit of Balls in a Bag/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,15 @@ tags:

### 方法一:二分查找

我们可以将题目可以转换为:对某个开销值,看它能不能在 maxOperations 次操作内得到。因此,二分枚举开销值,找到最小的且满足条件的开销值即可
本题需要我们最小化开销,即最小化单个袋子里球数目的最大值。随着最大值的增大,操作次数会减少,越容易满足条件

时间复杂度 $O(n \times \log M)$。其中 $n$ 和 $M$ 分别为数组 `nums` 的长度和最大值。
因此,我们可以二分枚举单个袋子里球数目的最大值,判断是否能在 $\textit{maxOperations}$ 次操作内得到。

具体地,我们定义二分查找的左边界 $l = 1$,右边界 $r = \max(\textit{nums})$。然后我们不断二分枚举中间值 $\textit{mid} = \frac{l + r}{2}$,对于每个 $\textit{mid}$,我们计算在这个 $\textit{mid}$ 下,需要的操作次数。如果操作次数小于等于 $\textit{maxOperations}$,说明 $\textit{mid}$ 满足条件,我们将右边界 $r$ 更新为 $\textit{mid}$,否则将左边界 $l$ 更新为 $\textit{mid} + 1$。

最后,我们返回左边界 $l$ 即可。

时间复杂度 $O(n \times \log M)$,其中 $n$ 和 $M$ 分别是数组 $\textit{nums}$ 的长度和最大值。空间复杂度 $O(1)$。

<!-- tabs:start -->

Expand All @@ -101,31 +107,28 @@ class Solution:
def check(mx: int) -> bool:
return sum((x - 1) // mx for x in nums) <= maxOperations

return bisect_left(range(1, max(nums)), True, key=check) + 1
return bisect_left(range(1, max(nums) + 1), True, key=check) + 1
```

#### Java

```java
class Solution {
public int minimumSize(int[] nums, int maxOperations) {
int left = 1, right = 0;
for (int x : nums) {
right = Math.max(right, x);
}
while (left < right) {
int mid = (left + right) >> 1;
long cnt = 0;
int l = 1, r = Arrays.stream(nums).max().getAsInt();
while (l < r) {
int mid = (l + r) >> 1;
long s = 0;
for (int x : nums) {
cnt += (x - 1) / mid;
s += (x - 1) / mid;
}
if (cnt <= maxOperations) {
right = mid;
if (s <= maxOperations) {
r = mid;
} else {
left = mid + 1;
l = mid + 1;
}
}
return left;
return l;
}
}
```
Expand All @@ -136,20 +139,20 @@ class Solution {
class Solution {
public:
int minimumSize(vector<int>& nums, int maxOperations) {
int left = 1, right = *max_element(nums.begin(), nums.end());
while (left < right) {
int mid = (left + right) >> 1;
long long cnt = 0;
int l = 1, r = ranges::max(nums);
while (l < r) {
int mid = (l + r) >> 1;
long long s = 0;
for (int x : nums) {
cnt += (x - 1) / mid;
s += (x - 1) / mid;
}
if (cnt <= maxOperations) {
right = mid;
if (s <= maxOperations) {
r = mid;
} else {
left = mid + 1;
l = mid + 1;
}
}
return left;
return l;
}
};
```
Expand All @@ -161,11 +164,11 @@ func minimumSize(nums []int, maxOperations int) int {
r := slices.Max(nums)
return 1 + sort.Search(r, func(mx int) bool {
mx++
cnt := 0
s := 0
for _, x := range nums {
cnt += (x - 1) / mx
s += (x - 1) / mx
}
return cnt <= maxOperations
return s <= maxOperations
})
}
```
Expand All @@ -174,21 +177,45 @@ func minimumSize(nums []int, maxOperations int) int {

```ts
function minimumSize(nums: number[], maxOperations: number): number {
let left = 1;
let right = Math.max(...nums);
while (left < right) {
const mid = (left + right) >> 1;
let cnt = 0;
for (const x of nums) {
cnt += ~~((x - 1) / mid);
}
if (cnt <= maxOperations) {
right = mid;
let [l, r] = [1, Math.max(...nums)];
while (l < r) {
const mid = (l + r) >> 1;
const s = nums.map(x => ((x - 1) / mid) | 0).reduce((a, b) => a + b);
if (s <= maxOperations) {
r = mid;
} else {
left = mid + 1;
l = mid + 1;
}
}
return left;
return l;
}
```

#### Rust

```rust
impl Solution {
pub fn minimum_size(nums: Vec<i32>, max_operations: i32) -> i32 {
let mut l = 1;
let mut r = *nums.iter().max().unwrap();

while l < r {
let mid = (l + r) / 2;
let mut s: i64 = 0;

for &x in &nums {
s += ((x - 1) / mid) as i64;
}

if s <= max_operations as i64 {
r = mid;
} else {
l = mid + 1;
}
}

l
}
}
```

Expand All @@ -201,24 +228,43 @@ function minimumSize(nums: number[], maxOperations: number): number {
* @return {number}
*/
var minimumSize = function (nums, maxOperations) {
let left = 1;
let right = Math.max(...nums);
while (left < right) {
const mid = (left + right) >> 1;
let cnt = 0;
for (const x of nums) {
cnt += ~~((x - 1) / mid);
}
if (cnt <= maxOperations) {
right = mid;
let [l, r] = [1, Math.max(...nums)];
while (l < r) {
const mid = (l + r) >> 1;
const s = nums.map(x => ((x - 1) / mid) | 0).reduce((a, b) => a + b);
if (s <= maxOperations) {
r = mid;
} else {
left = mid + 1;
l = mid + 1;
}
}
return left;
return l;
};
```

#### C#

```cs
public class Solution {
public int MinimumSize(int[] nums, int maxOperations) {
int l = 1, r = nums.Max();
while (l < r) {
int mid = (l + r) >> 1;
long s = 0;
foreach (int x in nums) {
s += (x - 1) / mid;
}
if (s <= maxOperations) {
r = mid;
} else {
l = mid + 1;
}
}
return l;
}
}
```

<!-- tabs:end -->

<!-- solution:end -->
Expand Down
Loading
Loading