题意:

有两种蛋糕,第一种蛋糕有图片说明 个,第二种蛋糕有图片说明 个,要求将这些蛋糕分到图片说明 个盘子里,分法必须满足下列要求:
1. 每个盘子里只能放一种蛋糕
2. 盘子不能为空
现在让你求出满足上述要求的前提下,装有最少蛋糕数量的盘子中装的蛋糕数量最多是多少?

解法一(暴力枚举答案)

有一个显然的结论,要让能够装的盘子越多,盘子中的蛋糕数量就必须要越少。
那么,我们已经枚举了盘子中蛋糕数量的最小值了,那么显然我们让每个盘子的蛋糕数量都为这个最小值,那么可装的盘子数量一定是最多的,即 均分 蛋糕一定是最优的。
具体的,我们从大到小枚举这个最小值图片说明 ,然后我们不妨先 均分 第一种蛋糕,再 均分 第二种蛋糕,然后再判断是否可以让每个盘子都有蛋糕,即 图片说明 ,如果可行直接返回图片说明 的值
代码:

class Solution {
public:
    int splitCake(int n, int a, int b) {
        //max(a,b):显然最大值要让两种蛋糕都至少有一种能放完一个盘子
        for(int i=max(a,b);i>=1;i--){
            if(a/i+b/i>=n)return i;
        }
        return 0;
    }
};

时间复杂度:图片说明 ,我们共循环了图片说明 次,循环体内是图片说明 的,故总的时间复杂度为图片说明
空间复杂度:图片说明 ,我们没有开额外的数组,没有递归调用的过程,只有有限个变量,故总的空间复杂度为图片说明

解法二(二分答案):

一个显然的结论:装有最少数量的蛋糕的盘子所装的蛋糕数量越小,所能够分的蛋糕份数(即盘子数)越大
我们记 图片说明
图片说明

显然,图片说明 是在图片说明 定义域内关于 图片说明 单调递减 的函数,如下图所示:

故我们可以将解法一中的枚举法改成二分法。
代码:
class Solution {
public:
    int splitCake(int n, int a, int b) {
        int l=1,r=max(a,b);//l和r分别是二分下界和上界
        int ans=0;//最后答案
        while(l<r){
            int mid=(l+r)>>1;
            if(a/mid+b/mid>=n){//如果当前mid可选,那么贪心地往mid右边继续寻找更优的答案
                ans=mid;
                l=mid+1;
            }else{//如果不满足,则在mid左边寻找答案
                r=mid;
            }
        }
        return ans;
    }
};

时间复杂度:图片说明 ,我们二分的范围大小是图片说明 ,循环体内是图片说明 的,故总的时间复杂度为图片说明
空间复杂度:图片说明 ,我们没有开额外的数组,没有递归调用的过程,只有有限个变量,故总的空间复杂度为图片说明