Skip to content

Commit 160b013

Browse files
authored
feat: add solutions to lc problem: No.2927 (#1945)
No.2927.Distribute Candies Among Children III
1 parent 5b70551 commit 160b013

File tree

11 files changed

+408
-0
lines changed

11 files changed

+408
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
# [2927. Distribute Candies Among Children III](https://leetcode.cn/problems/distribute-candies-among-children-iii)
2+
3+
[English Version](/solution/2900-2999/2927.Distribute%20Candies%20Among%20Children%20III/README_EN.md)
4+
5+
## 题目描述
6+
7+
<!-- 这里写题目描述 -->
8+
9+
<p>You are given two positive integers <code>n</code> and <code>limit</code>.</p>
10+
11+
<p>Return <em>the <strong>total number</strong> of ways to distribute </em><code>n</code> <em>candies among </em><code>3</code><em> children such that no child gets more than </em><code>limit</code><em> candies.</em></p>
12+
13+
<p>&nbsp;</p>
14+
<p><strong class="example">Example 1:</strong></p>
15+
16+
<pre>
17+
<strong>Input:</strong> n = 5, limit = 2
18+
<strong>Output:</strong> 3
19+
<strong>Explanation:</strong> There are 3 ways to distribute 5 candies such that no child gets more than 2 candies: (1, 2, 2), (2, 1, 2) and (2, 2, 1).
20+
</pre>
21+
22+
<p><strong class="example">Example 2:</strong></p>
23+
24+
<pre>
25+
<strong>Input:</strong> n = 3, limit = 3
26+
<strong>Output:</strong> 10
27+
<strong>Explanation:</strong> There are 10 ways to distribute 3 candies such that no child gets more than 3 candies: (0, 0, 3), (0, 1, 2), (0, 2, 1), (0, 3, 0), (1, 0, 2), (1, 1, 1), (1, 2, 0), (2, 0, 1), (2, 1, 0) and (3, 0, 0).
28+
</pre>
29+
30+
<p>&nbsp;</p>
31+
<p><strong>Constraints:</strong></p>
32+
33+
<ul>
34+
<li><code>1 &lt;= n &lt;= 10<sup>8</sup></code></li>
35+
<li><code>1 &lt;= limit &lt;= 10<sup>8</sup></code></li>
36+
</ul>
37+
38+
## 解法
39+
40+
<!-- 这里可写通用的实现逻辑 -->
41+
42+
**方法一:组合数学 + 容斥原理**
43+
44+
根据题目描述,我们需要将 $n$ 个糖果分给 $3$ 个小孩,每个小孩分到的糖果数在 $[0, limit]$ 之间。
45+
46+
这实际上等价于把 $n$ 个球放入 $3$ 个盒子中。由于盒子可以为空,我们可以再增加 $3$ 个虚拟球,然后再利用隔板法,即一共有 $n + 3$ 个球,我们在其中 $n + 3 - 1$ 个位置插入 $2$ 个隔板,从而将实际的 $n$ 个球分成 $3$ 组,并且允许盒子为空,因此初始方案数为 $C_{n + 2}^2$。
47+
48+
我们需要在这些方案中,排除掉存在盒子分到的小球数超过 $limit$ 的方案。考虑其中有一个盒子分到的小球数超过 $limit$,那么剩下的球(包括虚拟球)最多有 $n + 3 - (limit + 1) = n - limit + 2$ 个,位置数为 $n - limit + 1$,因此方案数为 $C_{n - limit + 1}^2$。由于存在 $3$ 个盒子,因此这样的方案数为 $3 \times C_{n - limit + 1}^2$。这样子算,我们会多排除掉同时存在两个盒子分到的小球数超过 $limit$ 的方案,因此我们需要再加上这样的方案数,即 $3 \times C_{n - 2 \times limit}^2$。
49+
50+
时间复杂度 $O(1)$,空间复杂度 $O(1)$。
51+
52+
<!-- tabs:start -->
53+
54+
### **Python3**
55+
56+
<!-- 这里可写当前语言的特殊实现逻辑 -->
57+
58+
```python
59+
class Solution:
60+
def distributeCandies(self, n: int, limit: int) -> int:
61+
if n > 3 * limit:
62+
return 0
63+
ans = comb(n + 2, 2)
64+
if n > limit:
65+
ans -= 3 * comb(n - limit + 1, 2)
66+
if n - 2 >= 2 * limit:
67+
ans += 3 * comb(n - 2 * limit, 2)
68+
return ans
69+
```
70+
71+
### **Java**
72+
73+
<!-- 这里可写当前语言的特殊实现逻辑 -->
74+
75+
```java
76+
class Solution {
77+
public long distributeCandies(int n, int limit) {
78+
if (n > 3 * limit) {
79+
return 0;
80+
}
81+
long ans = comb2(n + 2);
82+
if (n > limit) {
83+
ans -= 3 * comb2(n - limit + 1);
84+
}
85+
if (n - 2 >= 2 * limit) {
86+
ans += 3 * comb2(n - 2 * limit);
87+
}
88+
return ans;
89+
}
90+
91+
private long comb2(int n) {
92+
return 1L * n * (n - 1) / 2;
93+
}
94+
}
95+
```
96+
97+
### **C++**
98+
99+
```cpp
100+
class Solution {
101+
public:
102+
long long distributeCandies(int n, int limit) {
103+
auto comb2 = [](int n) {
104+
return 1LL * n * (n - 1) / 2;
105+
};
106+
if (n > 3 * limit) {
107+
return 0;
108+
}
109+
long long ans = comb2(n + 2);
110+
if (n > limit) {
111+
ans -= 3 * comb2(n - limit + 1);
112+
}
113+
if (n - 2 >= 2 * limit) {
114+
ans += 3 * comb2(n - 2 * limit);
115+
}
116+
return ans;
117+
}
118+
};
119+
```
120+
121+
### **Go**
122+
123+
```go
124+
func distributeCandies(n int, limit int) int64 {
125+
comb2 := func(n int) int {
126+
return n * (n - 1) / 2
127+
}
128+
if n > 3*limit {
129+
return 0
130+
}
131+
ans := comb2(n+2)
132+
if n > limit {
133+
ans -= 3 * comb2(n-limit+1)
134+
}
135+
if n-2 >= 2*limit {
136+
ans += 3 * comb2(n-2*limit)
137+
}
138+
return int64(ans)
139+
}
140+
```
141+
142+
### **TypeScript**
143+
144+
```ts
145+
function distributeCandies(n: number, limit: number): number {
146+
const comb2 = (n: number) => (n * (n - 1)) / 2;
147+
if (n > 3 * limit) {
148+
return 0;
149+
}
150+
let ans = comb2(n + 2);
151+
if (n > limit) {
152+
ans -= 3 * comb2(n - limit + 1);
153+
}
154+
if (n - 2 >= 2 * limit) {
155+
ans += 3 * comb2(n - 2 * limit);
156+
}
157+
return ans;
158+
}
159+
```
160+
161+
### **...**
162+
163+
```
164+
165+
```
166+
167+
<!-- tabs:end -->
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
# [2927. Distribute Candies Among Children III](https://leetcode.com/problems/distribute-candies-among-children-iii)
2+
3+
[中文文档](/solution/2900-2999/2927.Distribute%20Candies%20Among%20Children%20III/README.md)
4+
5+
## Description
6+
7+
<p>You are given two positive integers <code>n</code> and <code>limit</code>.</p>
8+
9+
<p>Return <em>the <strong>total number</strong> of ways to distribute </em><code>n</code> <em>candies among </em><code>3</code><em> children such that no child gets more than </em><code>limit</code><em> candies.</em></p>
10+
11+
<p>&nbsp;</p>
12+
<p><strong class="example">Example 1:</strong></p>
13+
14+
<pre>
15+
<strong>Input:</strong> n = 5, limit = 2
16+
<strong>Output:</strong> 3
17+
<strong>Explanation:</strong> There are 3 ways to distribute 5 candies such that no child gets more than 2 candies: (1, 2, 2), (2, 1, 2) and (2, 2, 1).
18+
</pre>
19+
20+
<p><strong class="example">Example 2:</strong></p>
21+
22+
<pre>
23+
<strong>Input:</strong> n = 3, limit = 3
24+
<strong>Output:</strong> 10
25+
<strong>Explanation:</strong> There are 10 ways to distribute 3 candies such that no child gets more than 3 candies: (0, 0, 3), (0, 1, 2), (0, 2, 1), (0, 3, 0), (1, 0, 2), (1, 1, 1), (1, 2, 0), (2, 0, 1), (2, 1, 0) and (3, 0, 0).
26+
</pre>
27+
28+
<p>&nbsp;</p>
29+
<p><strong>Constraints:</strong></p>
30+
31+
<ul>
32+
<li><code>1 &lt;= n &lt;= 10<sup>8</sup></code></li>
33+
<li><code>1 &lt;= limit &lt;= 10<sup>8</sup></code></li>
34+
</ul>
35+
36+
## Solutions
37+
38+
**Solution 1: Combinatorial Mathematics + Principle of Inclusion-Exclusion**
39+
40+
According to the problem description, we need to distribute $n$ candies to $3$ children, with each child receiving between $[0, limit]$ candies.
41+
42+
This is equivalent to placing $n$ balls into $3$ boxes. Since the boxes can be empty, we can add $3$ virtual balls, and then use the method of inserting partitions, i.e., there are a total of $n + 3$ balls, and we insert $2$ partitions among the $n + 3 - 1$ positions, thus dividing the actual $n$ balls into $3$ groups, and allowing the boxes to be empty. Therefore, the initial number of schemes is $C_{n + 2}^2$.
43+
44+
We need to exclude the schemes where the number of balls in a box exceeds $limit$. Consider that there is a box where the number of balls exceeds $limit$, then the remaining balls (including virtual balls) have at most $n + 3 - (limit + 1) = n - limit + 2$, and the number of positions is $n - limit + 1$, so the number of schemes is $C_{n - limit + 1}^2$. Since there are $3$ boxes, the number of such schemes is $3 \times C_{n - limit + 1}^2$. In this way, we will exclude too many schemes where the number of balls in two boxes exceeds $limit$ at the same time, so we need to add the number of such schemes, i.e., $3 \times C_{n - 2 \times limit}^2$.
45+
46+
The time complexity is $O(1)$, and the space complexity is $O(1)$.
47+
48+
<!-- tabs:start -->
49+
50+
### **Python3**
51+
52+
```python
53+
class Solution:
54+
def distributeCandies(self, n: int, limit: int) -> int:
55+
if n > 3 * limit:
56+
return 0
57+
ans = comb(n + 2, 2)
58+
if n > limit:
59+
ans -= 3 * comb(n - limit + 1, 2)
60+
if n - 2 >= 2 * limit:
61+
ans += 3 * comb(n - 2 * limit, 2)
62+
return ans
63+
```
64+
65+
### **Java**
66+
67+
```java
68+
class Solution {
69+
public long distributeCandies(int n, int limit) {
70+
if (n > 3 * limit) {
71+
return 0;
72+
}
73+
long ans = comb2(n + 2);
74+
if (n > limit) {
75+
ans -= 3 * comb2(n - limit + 1);
76+
}
77+
if (n - 2 >= 2 * limit) {
78+
ans += 3 * comb2(n - 2 * limit);
79+
}
80+
return ans;
81+
}
82+
83+
private long comb2(int n) {
84+
return 1L * n * (n - 1) / 2;
85+
}
86+
}
87+
```
88+
89+
### **C++**
90+
91+
```cpp
92+
class Solution {
93+
public:
94+
long long distributeCandies(int n, int limit) {
95+
auto comb2 = [](int n) {
96+
return 1LL * n * (n - 1) / 2;
97+
};
98+
if (n > 3 * limit) {
99+
return 0;
100+
}
101+
long long ans = comb2(n + 2);
102+
if (n > limit) {
103+
ans -= 3 * comb2(n - limit + 1);
104+
}
105+
if (n - 2 >= 2 * limit) {
106+
ans += 3 * comb2(n - 2 * limit);
107+
}
108+
return ans;
109+
}
110+
};
111+
```
112+
113+
### **Go**
114+
115+
```go
116+
func distributeCandies(n int, limit int) int64 {
117+
comb2 := func(n int) int {
118+
return n * (n - 1) / 2
119+
}
120+
if n > 3*limit {
121+
return 0
122+
}
123+
ans := comb2(n+2)
124+
if n > limit {
125+
ans -= 3 * comb2(n-limit+1)
126+
}
127+
if n-2 >= 2*limit {
128+
ans += 3 * comb2(n-2*limit)
129+
}
130+
return int64(ans)
131+
}
132+
```
133+
134+
### **TypeScript**
135+
136+
```ts
137+
function distributeCandies(n: number, limit: number): number {
138+
const comb2 = (n: number) => (n * (n - 1)) / 2;
139+
if (n > 3 * limit) {
140+
return 0;
141+
}
142+
let ans = comb2(n + 2);
143+
if (n > limit) {
144+
ans -= 3 * comb2(n - limit + 1);
145+
}
146+
if (n - 2 >= 2 * limit) {
147+
ans += 3 * comb2(n - 2 * limit);
148+
}
149+
return ans;
150+
}
151+
```
152+
153+
### **...**
154+
155+
```
156+
157+
```
158+
159+
<!-- tabs:end -->
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
class Solution {
2+
public:
3+
long long distributeCandies(int n, int limit) {
4+
auto comb2 = [](int n) {
5+
return 1LL * n * (n - 1) / 2;
6+
};
7+
if (n > 3 * limit) {
8+
return 0;
9+
}
10+
long long ans = comb2(n + 2);
11+
if (n > limit) {
12+
ans -= 3 * comb2(n - limit + 1);
13+
}
14+
if (n - 2 >= 2 * limit) {
15+
ans += 3 * comb2(n - 2 * limit);
16+
}
17+
return ans;
18+
}
19+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
func distributeCandies(n int, limit int) int64 {
2+
comb2 := func(n int) int {
3+
return n * (n - 1) / 2
4+
}
5+
if n > 3*limit {
6+
return 0
7+
}
8+
ans := comb2(n+2)
9+
if n > limit {
10+
ans -= 3 * comb2(n-limit+1)
11+
}
12+
if n-2 >= 2*limit {
13+
ans += 3 * comb2(n-2*limit)
14+
}
15+
return int64(ans)
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
class Solution {
2+
public long distributeCandies(int n, int limit) {
3+
if (n > 3 * limit) {
4+
return 0;
5+
}
6+
long ans = comb2(n + 2);
7+
if (n > limit) {
8+
ans -= 3 * comb2(n - limit + 1);
9+
}
10+
if (n - 2 >= 2 * limit) {
11+
ans += 3 * comb2(n - 2 * limit);
12+
}
13+
return ans;
14+
}
15+
16+
private long comb2(int n) {
17+
return 1L * n * (n - 1) / 2;
18+
}
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
class Solution:
2+
def distributeCandies(self, n: int, limit: int) -> int:
3+
if n > 3 * limit:
4+
return 0
5+
ans = comb(n + 2, 2)
6+
if n > limit:
7+
ans -= 3 * comb(n - limit + 1, 2)
8+
if n - 2 >= 2 * limit:
9+
ans += 3 * comb(n - 2 * limit, 2)
10+
return ans

0 commit comments

Comments
 (0)