每日一题_1894. 找到需要补充粉笔的学生编号

每日一题_1894. 找到需要补充粉笔的学生编号

leetcode_1894
原题

题意分析

今天教师节,然后leetcode就很应景的整了个这个题
通过读题,该题的意思是说,有n个学生,这n个学生轮流上黑板做题(确定做题?这么多粉笔都可以把黑板涂满了),做题会用粉笔,每个学生上去做题用的粉笔不一样,但都是定值,用一个数组来表示,然后粉笔盒里有k支粉笔。这n个学生就一直轮流上去做题,直到把粉笔盒里的k支粉笔用完,然后轮到最后的那个学生会因为粉笔不够而没法做题,题目就是让我们返回这个最后的学生的编号。

分析完题意后最直接的想法既然轮流做题,那么我们可以用 i 表示学生来模拟,到了超过 n 的时候模 n,这样就表示新的一轮,每次都将k减去花掉的粉笔,这样模拟知道 k 小于当前学生所花的粉笔,但是一看数据要求 n 最大10^5,k 最大10 ^9,这样模拟时间复杂度肯定会炸。

继续思考,其实我们只关注最后一个,其实一轮下来学生所花的粉笔是定值,那么我们用k对一轮所花的粉笔取余,就得到了我们最后一轮粉笔不够时的数量,然后去模拟,这样就不会炸了。

再思考一下,其实每个学生上去一次,花费的粉笔的数量就会累加,直到超出粉笔盒粉笔的数量,那么针对最后一轮,其实我们就是在找何时累加的粉笔数量到达临界点,就是加上这个学生数量就会超过粉笔盒内粉笔的数量。这中累加的情况,我们就会想到前缀和,然后找这中临界点(边界),临界点的一边满足条件,边界点的另一边不满足条件。这是就应想到二分。综上分析,最终采用的算法就是 前缀和 + 二分 来解决。

代码:

    int chalkReplacer(vector<int>& chalk, int k) {
        int n = chalk.size();
        vector<long long> s(n + 1, 0);
        for (int i = 1; i <= n; i ++) s[i] = s[i - 1] + chalk[i - 1];

        long long remain = k % s[n];

        int l = 1, r = n;
        while (l < r)
        {
            int mid = l + r >> 1;
            if (s[mid] > remain) r = mid;
            else l = mid + 1;
        }
        return l - 1;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值