小C的糖果分配问题
问题描述
小C有一堆糖果,总共有n颗。她需要将糖果分给小朋友们,每个小朋友的糖果数量必须在l到r之间。她想知道,在满足这些条件的前提下,最少可以分给多少个小朋友,最多可以分给多少个小朋友。如果糖果无法正好分完,返回-1
。
测试样例
样例1:
输入:
n = 10,l = 2,r = 3
输出:[4, 5]
样例2:
输入:
n = 7,l = 3,r = 5
输出:[2, 2]
样例3:
输入:
n = 8,l = 1,r = 4
输出:[2, 8]
题目分析和算法解析
单纯是考察一个数学知识,主要考察Math库中常见函数的运用
核心就是问最少可以分给多少个小朋友,最多可以分给多少个小朋友。
题目要求我们考虑如何在给定的范围 [l, r]
内分配糖果
分给最少个朋友,那每个朋友分多一点糖果 分给最多个朋友,每个朋友就分少一点糖果
这里用到Math库中的方法,floor是地板,ceil是天花板。
下面:
int maxChildren = n / l
和
int maxChildren = (int) Math.floor((double) n / l);
是等价的
Math.ceil(double a)
- 向上取整
功能:返回大于或等于参数 a
的最小整数值,类型为 double
。如果参数 a
是整数,返回值就是 a
本身;如果参数 a
有小数部分,则返回大于 a
的最小整数。
例子:
System.out.println(Math.ceil(4.2)); // 输出:5.0 System.out.println(Math.ceil(-4.8)); // 输出:-4.0 System.out.println(Math.ceil(5.0)); // 输出:5.0
解释:ceil
方法表示 向上取整,即向正无穷方向取整。即使小数部分很小,也会将它向上取整到最近的整数。
Math.floor(double a)
- 向下取整
功能:返回小于或等于参数 a
的最大整数值,类型为 double
。如果参数 a
是整数,返回值就是 a
本身;如果参数 a
有小数部分,则返回小于 a
的最大整数。
System.out.println(Math.floor(4.2)); // 输出:4.0 System.out.println(Math.floor(-4.8)); // 输出:-5.0 System.out.println(Math.floor(5.0)); // 输出:5.0
解释:floor
方法表示 向下取整,即向负无穷方向取整。如果有小数部分,它会舍去小数并返回比原数小的整数。
Math常见的函数有:
-----函数---| - 描述- | 例子 ----------------- |
Math.ceil() | 向上取整 | Math.ceil(4.2) 返回 5.0 |
---|
Math.floor() | 向下取整 | Math.floor(4.7) 返回 4.0 |
---|
Math.round() | 四舍五入 | Math.round(4.5) 返回 5 |
---|
Math.rint() | 最接近的整数(偏向偶数) | Math.rint(4.5) 返回 4.0 |
---|
Math.abs() | 取绝对值 | Math.abs(-4.7) 返回 4.7 |
---|
Math.rint(double a)
- 最接近的整数(返回 double
)
功能:返回与参数 a
最接近的整数值,并以 double
形式表示。如果两个整数同样接近,则取偶数值。
例子:
System.out.println(Math.rint(4.5)); // 输出:4.0 System.out.println(Math.rint(5.5)); // 输出:6.0 System.out.println(Math.rint(4.4)); // 输出:4.0
解释:rint
类似于 round
,但它返回 double
,而且对于刚好处于两个整数中间的值,它会偏向偶数(银行家舍入法)
代码实现
import java.util.Arrays;
public class Main {
public static int[] solution(int n, int l, int r) {
// 计算最少人数
int minChildren = (int) Math.ceil((double) n / r);
// 计算最多人数
// int maxChildren = n / l;
int maxChildren = (int) Math.floor((double) n / l);
// 检查是否满足条件:糖果能正好分完
if (minChildren * l > n || maxChildren * r < n) {
return new int[] { -1 };
}
return new int[] { minChildren, maxChildren };
}
}
时间复杂度和空间复杂度的分析
都是常数级复杂度
时间复杂度:O(1)
,因为我们只需要进行一些基本的算术运算。
空间复杂度:O(1)
,没有额外的空间消耗。