【每日一题】2591. 将钱分给最多的儿童

文章目录

  • Tag
  • 题目来源
  • 题目解读
  • 解题思路
    • 思路一
    • 思路二
  • 写在最后

Tag

【贪心】【2023-09-22】


题目来源

2591. 将钱分给最多的儿童

【每日一题】2591. 将钱分给最多的儿童_第1张图片

题目解读

有一些钱 money 美元要分给 children 个儿童,分配规则如下:

  • 所有的钱必须被分配完;
  • 每个儿童至少获得 1 美元;
  • 没有人获得 4 美元。

请返回按照上述分配规则分配 money 美元,最多有多少个儿童恰好获得 8 美元。


解题思路

本题的解题思路都是【贪心】,以下给出的是两种思考方式,思路一循序渐进的思考,思路二是一步到位的思考(更考验脑筋)。

思路一

既然每个人至少获得 1 美元,那就先给每个人分配一美元,还剩下 money = money - children 美元,我们要尽可能多的给儿童分配 8美元,因此接下来需要尽可能多的给儿童分配 7 美元( 8 − 1 = 7 8 - 1 = 7 81=7)。

c n t = m i n ( ⌊ m o n e y 7 ⌋ , c h i l d r e n ) cnt = min(\lfloor \frac{money}{7} \rfloor, children) cnt=min(⌊7money,children)cnt 表示剩下的钱做多可以分配的儿童数),这时候剩余的总钱数为 money = money - 7 * cnt,没有获得 8 美元的儿童数为 children = children - cnt,接下来需要对剩余的总钱数 money 以及进行没有获得 8 美元的儿童数 children 进行判断:

  • 如果 children = 0 并且 money > 0,说明此时每个儿童都被分配到了 8 美元,但是还剩下一点钱,本着钱要被分配完的原则,需要将剩下的钱都分配给某一个儿童即 cnt - 1,这样才可以保证有最多数量的儿童获得 8 美元。
  • 如果 children = 1 并且 money = 3,此时不能将剩下的 3 美元给到这个没有获得 8 美元的儿童,因为每个儿童都不能获得 4 美元,因此需要将剩下的 3 美元分配给 2 个儿童,刚刚剩下的儿童占了一个分配名额,另一个要分配给获得 8 美元的儿童中的一个,即 cnt - 1,这样才可以保证有最多数量的儿童获得 8 美元。
  • 其他情况下,cnt 没有变化。

特殊的,如果一开始分配之前 children > money,那么根本不会满足 “每个儿童至少获得 1 美元” 的分配要求,直接返回 -1

实现代码

class Solution {
public:
    int distMoney(int money, int children) {
        if (money < children)
            return -1;

        money -= children;
        int cnt = min(money / 7, children);
        children -= cnt;
        money -= 7 * cnt;

        if (children == 0 && money > 0 || children == 1 && money == 3)
            -- cnt;
        return cnt;
    }
};

复杂度分析

时间复杂度: O ( 1 ) O(1) O(1)

空间复杂度: O ( 1 ) O(1) O(1)

思路二

直接思考:

  • 如果每个人都够被分配 8 美元即 money >= 8 * children,那么至少有 children - 1 个儿童获得 8 美元,如果相等那就是所有 children 都可以获得 8 美元;
  • 如果这笔钱仅仅够 children - 1 个人分配 8 美元,并且还剩下 4 美元,那么最多只能分配给 children - 2 个人 8 美元(因为剩下的那个儿童不能获得 4 美元,因此需要分配给一个获得 8 美元的儿童);
  • 其他情况只需要先保证每个儿童至少获得 1 美元,接着对 7 取下整即可。

综上:

  • 如果 money > 8 * children,直接返回 children - 1
  • 如果 money = 8 * children - 4,直接返回 children - 2
  • 其他情况下直接返回 (money - children) / 7

特殊的,如果一开始分配之前 children > money,那么根本不会满足 “每个儿童至少获得 1 美元” 的分配要求,直接返回 -1

实现代码

class Solution {
public:
    int distMoney(int money, int children) {
        if (money < children)
            return -1;

        if (money > 8 * children) 
            return children - 1;

        if (money == 8 * children - 4)
            return children - 2;

        return (money - children) / 7;
    }  
};

复杂度分析

时间复杂度: O ( 1 ) O(1) O(1)

空间复杂度: O ( 1 ) O(1) O(1)


写在最后

如果文章内容有任何错误或者您对文章有任何疑问,欢迎私信博主或者在评论区指出 。

如果大家有更优的时间、空间复杂度方法,欢迎评论区交流。

最后,感谢您的阅读,如果感到有所收获的话可以给博主点一个 哦。

你可能感兴趣的:(LeetCode每日一题,贪心,2023-09-22,C++,算法)