题目:
给你一个整数
money
,表示你总共有的钱数(单位为美元)和另一个整数children
,表示你要将钱分配给多少个儿童。你需要按照如下规则分配:
- 所有的钱都必须被分配。
- 每个儿童至少获得
1
美元。- 没有人获得
4
美元。请你按照上述规则分配金钱,并返回 最多 有多少个儿童获得 恰好
8
美元。如果没有任何分配方案,返回-1
。
class Solution {
public int distMoney(int money, int children) {
if(money < children) {
return -1;
}
// 为了满足题意每个儿童都获得至少1美元
// 现在money-children相当于每个儿童分得了1美元
money -= children;
// 这一步的作用在于筛选最多分有8美元的儿童,分两种情况
// 1)money/7 > children 算出来的个数大于儿童数,则cnt=children。
// 说明每个儿童都可获取8美元的前提下,并且还有多余的钱
// 2) money/7 < children 算出来的个数小于儿童数,则cnt=money/7。
// 说明现有的钱只有money/7个儿童可获得
// 变量cnt记录可以最多获取8美元的儿童数量
int cnt = Math.min(money/7,children);
// 计算最多的儿童获取8美元之后,剩余的美元数量
money = money - (7 * cnt);
// 计算剩下多少儿童未获得8美元
children -= cnt;
// 1.若剩余 0个人,并且 money>0,那么将所有的美元分配给一个已经分到8 美元的人,
// 令 cnt 减去 1。
// 2.若剩余 1 个人,并且 money=3,为了避免分到 4 美元,并注意到题目输入中的
// children>=2,因此将这 3 美元拆成两部分,将其中的一部分分配给已经分到 8 美元
// 的人,令cnt 减去 1。
// 3.对于其他情况,若 money>0,可以将所有美元分配给一个人,cnt 不变,直接ruturn cnt。
// 这种情况也很好理解,例如 剩余0人,money=0,直接return cnt;
// 别忘了这时候剩下的人都是至少有1美元的,所以排除了上面第二种情况避免有剩下的
// 人分到4美元,那么这个时候在剩余money小于7美元的情况下只要人数和money不等于
// 第二种情况,无论还剩下多少个儿童和剩下多少美元(0-6美元),都不会出现
// 有儿童分到4美元的情况,所以直接return cnt。
if((children == 0 && money > 0) || (children == 1 && money == 3)) {
cnt -= 1;
}
return cnt;
}
}
// 变量cnt记录可以最多获取8美元的儿童数量
int cnt = Math.min(money/7,children);
// 计算最多的儿童获取8美元之后,剩余的美元数量
money = money - (7 * cnt);说明:这两步保证了剩余的美元不会超过7 美元,只能在0-6美元
复杂度分析
时间复杂度:O(1)。
空间复杂度:O(1)。