Skip to content
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

feat: add solutions to lc problem: No.2226 #3759

Merged
merged 1 commit into from
Nov 13, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,11 @@ tags:

### 方法一:二分查找

时间复杂度 $O(nlogn)$。
我们注意到,如果每个小孩能分到糖果数 $v$,那么对于任意 $v' \lt v$,每个小孩也能分到 $v'$ 颗糖果。因此,我们可以使用二分查找的方法找到最大的 $v$,使得每个小孩能分到 $v$ 颗糖果。

我们定义二分查找的左边界 $l = 0$,右边界 $r = \max(\text{candies})$,其中 $\max(\text{candies})$ 表示数组 $\text{candies}$ 中的最大值。在二分查找的过程中,我们每次取 $v$ 的中间值 $v = \left\lfloor \frac{l + r + 1}{2} \right\rfloor$,然后计算每个小孩能分到的糖果数 $v$ 的总和,如果总和大于等于 $k$,则说明每个小孩能分到 $v$ 颗糖果,此时我们更新左边界 $l = v$,否则我们更新右边界 $r = v - 1$。最终,当 $l = r$ 时,我们找到了最大的 $v$。

时间复杂度 $O(n \times \log M)$,其中 $n$ 表示数组 $\text{candies}$ 的长度,而 $M$ 表示数组 $\text{candies}$ 中的最大值。空间复杂度 $O(1)$。

<!-- tabs:start -->

Expand All @@ -70,36 +74,35 @@ tags:
```python
class Solution:
def maximumCandies(self, candies: List[int], k: int) -> int:
left, right = 0, max(candies)
while left < right:
mid = (left + right + 1) >> 1
cnt = sum(v // mid for v in candies)
if cnt >= k:
left = mid
l, r = 0, max(candies)
while l < r:
mid = (l + r + 1) >> 1
if sum(x // mid for x in candies) >= k:
l = mid
else:
right = mid - 1
return left
r = mid - 1
return l
```

#### Java

```java
class Solution {
public int maximumCandies(int[] candies, long k) {
int left = 0, right = (int) 1e7;
while (left < right) {
int mid = (left + right + 1) >> 1;
int l = 0, r = Arrays.stream(candies).max().getAsInt();
while (l < r) {
int mid = (l + r + 1) >> 1;
long cnt = 0;
for (int v : candies) {
cnt += v / mid;
for (int x : candies) {
cnt += x / mid;
}
if (cnt >= k) {
left = mid;
l = mid;
} else {
right = mid - 1;
r = mid - 1;
}
}
return left;
return l;
}
}
```
Expand All @@ -110,17 +113,20 @@ class Solution {
class Solution {
public:
int maximumCandies(vector<int>& candies, long long k) {
int left = 0, right = 1e7;
while (left < right) {
int mid = (left + right + 1) >> 1;
int l = 0, r = ranges::max(candies);
while (l < r) {
int mid = (l + r + 1) >> 1;
long long cnt = 0;
for (int& v : candies) cnt += v / mid;
if (cnt >= k)
left = mid;
else
right = mid - 1;
for (int x : candies) {
cnt += x / mid;
}
if (cnt >= k) {
l = mid;
} else {
r = mid - 1;
}
}
return left;
return l;
}
};
```
Expand All @@ -129,20 +135,32 @@ public:

```go
func maximumCandies(candies []int, k int64) int {
left, right := 0, int(1e7)
for left < right {
mid := (left + right + 1) >> 1
return sort.Search(1e7, func(v int) bool {
v++
var cnt int64
for _, v := range candies {
cnt += int64(v / mid)
for _, x := range candies {
cnt += int64(x / v)
}
if cnt >= k {
left = mid
} else {
right = mid - 1
}
}
return left
return cnt < k
})
}
```

#### TypeScript

```ts
function maximumCandies(candies: number[], k: number): number {
let [l, r] = [0, Math.max(...candies)];
while (l < r) {
const mid = (l + r + 1) >> 1;
const cnt = candies.reduce((acc, cur) => acc + Math.floor(cur / mid), 0);
if (cnt >= k) {
l = mid;
} else {
r = mid - 1;
}
}
return l;
}
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,13 @@ tags:

<!-- solution:start -->

### Solution 1
### Solution 1: Binary Search

We notice that if each child can receive $v$ candies, then for any $v' \lt v$, each child can also receive $v'$ candies. Therefore, we can use binary search to find the maximum $v$ such that each child can receive $v$ candies.

We define the left boundary of the binary search as $l = 0$ and the right boundary as $r = \max(\text{candies})$, where $\max(\text{candies})$ represents the maximum value in the array $\text{candies}$. During the binary search, we take the middle value $v = \left\lfloor \frac{l + r + 1}{2} \right\rfloor$ each time, and then calculate the total number of candies each child can receive. If the total is greater than or equal to $k$, it means each child can receive $v$ candies, so we update the left boundary $l = v$. Otherwise, we update the right boundary $r = v - 1$. Finally, when $l = r$, we have found the maximum $v$.

The time complexity is $O(n \times \log M)$, where $n$ is the length of the array $\text{candies}$, and $M$ is the maximum value in the array $\text{candies}$. The space complexity is $O(1)$.

<!-- tabs:start -->

Expand All @@ -65,36 +71,35 @@ tags:
```python
class Solution:
def maximumCandies(self, candies: List[int], k: int) -> int:
left, right = 0, max(candies)
while left < right:
mid = (left + right + 1) >> 1
cnt = sum(v // mid for v in candies)
if cnt >= k:
left = mid
l, r = 0, max(candies)
while l < r:
mid = (l + r + 1) >> 1
if sum(x // mid for x in candies) >= k:
l = mid
else:
right = mid - 1
return left
r = mid - 1
return l
```

#### Java

```java
class Solution {
public int maximumCandies(int[] candies, long k) {
int left = 0, right = (int) 1e7;
while (left < right) {
int mid = (left + right + 1) >> 1;
int l = 0, r = Arrays.stream(candies).max().getAsInt();
while (l < r) {
int mid = (l + r + 1) >> 1;
long cnt = 0;
for (int v : candies) {
cnt += v / mid;
for (int x : candies) {
cnt += x / mid;
}
if (cnt >= k) {
left = mid;
l = mid;
} else {
right = mid - 1;
r = mid - 1;
}
}
return left;
return l;
}
}
```
Expand All @@ -105,17 +110,20 @@ class Solution {
class Solution {
public:
int maximumCandies(vector<int>& candies, long long k) {
int left = 0, right = 1e7;
while (left < right) {
int mid = (left + right + 1) >> 1;
int l = 0, r = ranges::max(candies);
while (l < r) {
int mid = (l + r + 1) >> 1;
long long cnt = 0;
for (int& v : candies) cnt += v / mid;
if (cnt >= k)
left = mid;
else
right = mid - 1;
for (int x : candies) {
cnt += x / mid;
}
if (cnt >= k) {
l = mid;
} else {
r = mid - 1;
}
}
return left;
return l;
}
};
```
Expand All @@ -124,20 +132,32 @@ public:

```go
func maximumCandies(candies []int, k int64) int {
left, right := 0, int(1e7)
for left < right {
mid := (left + right + 1) >> 1
return sort.Search(1e7, func(v int) bool {
v++
var cnt int64
for _, v := range candies {
cnt += int64(v / mid)
for _, x := range candies {
cnt += int64(x / v)
}
if cnt >= k {
left = mid
} else {
right = mid - 1
}
}
return left
return cnt < k
})
}
```

#### TypeScript

```ts
function maximumCandies(candies: number[], k: number): number {
let [l, r] = [0, Math.max(...candies)];
while (l < r) {
const mid = (l + r + 1) >> 1;
const cnt = candies.reduce((acc, cur) => acc + Math.floor(cur / mid), 0);
if (cnt >= k) {
l = mid;
} else {
r = mid - 1;
}
}
return l;
}
```

Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
class Solution {
public:
int maximumCandies(vector<int>& candies, long long k) {
int left = 0, right = 1e7;
while (left < right) {
int mid = (left + right + 1) >> 1;
int l = 0, r = ranges::max(candies);
while (l < r) {
int mid = (l + r + 1) >> 1;
long long cnt = 0;
for (int& v : candies) cnt += v / mid;
if (cnt >= k)
left = mid;
else
right = mid - 1;
for (int x : candies) {
cnt += x / mid;
}
if (cnt >= k) {
l = mid;
} else {
r = mid - 1;
}
}
return left;
return l;
}
};
};
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
func maximumCandies(candies []int, k int64) int {
left, right := 0, int(1e7)
for left < right {
mid := (left + right + 1) >> 1
return sort.Search(1e7, func(v int) bool {
v++
var cnt int64
for _, v := range candies {
cnt += int64(v / mid)
for _, x := range candies {
cnt += int64(x / v)
}
if cnt >= k {
left = mid
} else {
right = mid - 1
}
}
return left
}
return cnt < k
})
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
class Solution {
public int maximumCandies(int[] candies, long k) {
int left = 0, right = (int) 1e7;
while (left < right) {
int mid = (left + right + 1) >> 1;
int l = 0, r = Arrays.stream(candies).max().getAsInt();
while (l < r) {
int mid = (l + r + 1) >> 1;
long cnt = 0;
for (int v : candies) {
cnt += v / mid;
for (int x : candies) {
cnt += x / mid;
}
if (cnt >= k) {
left = mid;
l = mid;
} else {
right = mid - 1;
r = mid - 1;
}
}
return left;
return l;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
class Solution:
def maximumCandies(self, candies: List[int], k: int) -> int:
left, right = 0, max(candies)
while left < right:
mid = (left + right + 1) >> 1
cnt = sum(v // mid for v in candies)
if cnt >= k:
left = mid
l, r = 0, max(candies)
while l < r:
mid = (l + r + 1) >> 1
if sum(x // mid for x in candies) >= k:
l = mid
else:
right = mid - 1
return left
r = mid - 1
return l
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
function maximumCandies(candies: number[], k: number): number {
let [l, r] = [0, Math.max(...candies)];
while (l < r) {
const mid = (l + r + 1) >> 1;
const cnt = candies.reduce((acc, cur) => acc + Math.floor(cur / mid), 0);
if (cnt >= k) {
l = mid;
} else {
r = mid - 1;
}
}
return l;
}
Loading