原文链接: https://leetcode-cn.com/problems/find-the-student-that-will-replace-the-chalk
英文原文
There are n
students in a class numbered from 0
to n - 1
. The teacher will give each student a problem starting with the student number 0
, then the student number 1
, and so on until the teacher reaches the student number n - 1
. After that, the teacher will restart the process, starting with the student number 0
again.
You are given a 0-indexed integer array chalk
and an integer k
. There are initially k
pieces of chalk. When the student number i
is given a problem to solve, they will use chalk[i]
pieces of chalk to solve that problem. However, if the current number of chalk pieces is strictly less than chalk[i]
, then the student number i
will be asked to replace the chalk.
Return the index of the student that will replace the chalk.
Example 1:
Input: chalk = [5,1,5], k = 22 Output: 0 Explanation: The students go in turns as follows: - Student number 0 uses 5 chalk, so k = 17. - Student number 1 uses 1 chalk, so k = 16. - Student number 2 uses 5 chalk, so k = 11. - Student number 0 uses 5 chalk, so k = 6. - Student number 1 uses 1 chalk, so k = 5. - Student number 2 uses 5 chalk, so k = 0. Student number 0 does not have enough chalk, so they will have to replace it.
Example 2:
Input: chalk = [3,4,1,2], k = 25 Output: 1 Explanation: The students go in turns as follows: - Student number 0 uses 3 chalk so k = 22. - Student number 1 uses 4 chalk so k = 18. - Student number 2 uses 1 chalk so k = 17. - Student number 3 uses 2 chalk so k = 15. - Student number 0 uses 3 chalk so k = 12. - Student number 1 uses 4 chalk so k = 8. - Student number 2 uses 1 chalk so k = 7. - Student number 3 uses 2 chalk so k = 5. - Student number 0 uses 3 chalk so k = 2. Student number 1 does not have enough chalk, so they will have to replace it.
Constraints:
chalk.length == n
1 <= n <= 105
1 <= chalk[i] <= 105
1 <= k <= 109
中文题目
一个班级里有 n
个学生,编号为 0
到 n - 1
。每个学生会依次回答问题,编号为 0
的学生先回答,然后是编号为 1
的学生,以此类推,直到编号为 n - 1
的学生,然后老师会重复这个过程,重新从编号为 0
的学生开始回答问题。
给你一个长度为 n
且下标从 0
开始的整数数组 chalk
和一个整数 k
。一开始粉笔盒里总共有 k
支粉笔。当编号为 i
的学生回答问题时,他会消耗 chalk[i]
支粉笔。如果剩余粉笔数量 严格小于 chalk[i]
,那么学生 i
需要 补充 粉笔。
请你返回需要 补充 粉笔的学生 编号 。
示例 1:
输入:chalk = [5,1,5], k = 22 输出:0 解释:学生消耗粉笔情况如下: - 编号为 0 的学生使用 5 支粉笔,然后 k = 17 。 - 编号为 1 的学生使用 1 支粉笔,然后 k = 16 。 - 编号为 2 的学生使用 5 支粉笔,然后 k = 11 。 - 编号为 0 的学生使用 5 支粉笔,然后 k = 6 。 - 编号为 1 的学生使用 1 支粉笔,然后 k = 5 。 - 编号为 2 的学生使用 5 支粉笔,然后 k = 0 。 编号为 0 的学生没有足够的粉笔,所以他需要补充粉笔。
示例 2:
输入:chalk = [3,4,1,2], k = 25 输出:1 解释:学生消耗粉笔情况如下: - 编号为 0 的学生使用 3 支粉笔,然后 k = 22 。 - 编号为 1 的学生使用 4 支粉笔,然后 k = 18 。 - 编号为 2 的学生使用 1 支粉笔,然后 k = 17 。 - 编号为 3 的学生使用 2 支粉笔,然后 k = 15 。 - 编号为 0 的学生使用 3 支粉笔,然后 k = 12 。 - 编号为 1 的学生使用 4 支粉笔,然后 k = 8 。 - 编号为 2 的学生使用 1 支粉笔,然后 k = 7 。 - 编号为 3 的学生使用 2 支粉笔,然后 k = 5 。 - 编号为 0 的学生使用 3 支粉笔,然后 k = 2 。 编号为 1 的学生没有足够的粉笔,所以他需要补充粉笔。
提示:
chalk.length == n
1 <= n <= 105
1 <= chalk[i] <= 105
1 <= k <= 109
通过代码
高赞题解
前缀和 + 二分
根据题意,每个学生消耗的粉笔为定值,所有粉笔最终会像老师的教导一样孜孜不倦地循环投入在所有的学生身上。
因此我们可以预处理出前缀和数组 $sum$,将 $k$ 对所有学生一次循环所消耗总粉笔数($sum[n]$)进行取模,得到最后一轮开始前的粉笔数量。
然后对前缀和数组进行二分,找到最后一位满足粉笔要求的学生,其往后一位的同学编号即是答案。
代码:
class Solution {
public int chalkReplacer(int[] chalk, int k) {
int n = chalk.length;
long[] sum = new long[n + 1];
for (int i = 1; i <= n; i++) sum[i] = sum[i - 1] + chalk[i - 1];
k = (int)(k % sum[n]);
int l = 1, r = n;
while (l < r) {
int mid = l + r + 1 >> 1;
if (sum[mid] <= k) l = mid;
else r = mid - 1;
}
return sum[r] <= k ? r : r - 1;
}
}
- 时间复杂度:预处理前缀和的复杂度为 $O(n)$;二分求答案的复杂度为 $O(\log{n})$。整体复杂度为 $O(n)$
- 空间复杂度:$O(n)$
模拟
通过解法一,我们发现复杂度的上界为预处理前缀和的复杂度 $O(n)$,同时「对单次循环消耗的总粉笔数取模操作」确保了剩余的粉笔数必然会在单次遍历中消耗完成。
因此 $O(\log{n})$ 的二分其实是没有必要的,只需要再对 chalk
进行最后一轮的遍历模拟即可。
代码:
class Solution {
public int chalkReplacer(int[] chalk, int k) {
int n = chalk.length;
long max = 0;
for (int i : chalk) max += i;
k = (int)(k % max);
for (int i = 0; i < n; i++) {
k -= chalk[i];
if (k < 0) return i;
}
return -1; // never
}
}
- 时间复杂度:$O(n)$
- 空间复杂度:$O(1)$
最后
如果有帮助到你,请给题解点个赞和收藏,让更多的人看到 ~ (“▔□▔)/
也欢迎你 关注我(公主号后台回复「送书」即可参与长期看题解学算法送实体书活动)或 加入「组队打卡」小群 ,提供写「证明」&「思路」的高质量题解。
所有题解已经加入 刷题指南,欢迎 star 哦 ~
统计信息
通过次数 | 提交次数 | AC比率 |
---|---|---|
37772 | 82596 | 45.7% |
提交历史
提交时间 | 提交结果 | 执行时间 | 内存消耗 | 语言 |
---|