2026-11-02:统计每个班次结束后的未完成任务数。用go语言,给定两个整数数组 tasks 和 shifts。tasks 中每个元素表示对应任务需要消耗的

🤖 AI总结

主题

用Go/Python/C++解决力扣4012题:统计每个班次结束后的未完成任务数。

摘要

通过前缀和与二分查找,按班次累计时间计算未完成任务数,完成全部任务时重置累计时间。

关键信息

  • 1 将tasks转为前缀和,用二分查找定位已完成任务数。
  • 2 累计班次时间,完成全部任务时重置并记0。
  • 3 时间复杂度O(n + m log n),空间O(1)。

2026-11-02:统计每个班次结束后的未完成任务数。用go语言,给定两个整数数组 tasks 和 shifts。tasks 中每个元素表示对应任务需要消耗的时间;shifts 中每个元素表示对应班次可提供的工作时间。所有任务只能按照给定先后顺序依次处理。如果某个班次结束时当前任务还没有做完,那么下一个班次会从该任务已经完成的位置继续处理,而不是重新开始该任务。如果某个班次内把所有任务都完成了,则该班次立即结束,剩余时间作废,后续班次会从第一个任务重新开始处理。所谓未完成任务,是指尚未被完整处理完的任务,正在处理但还没有结束的任务也计入未完成。需要返回 ans,其中 ans[j] 表示第 j 个班次结束后仍未完成的任务数量。

1 <= tasks.length <= 100000。

1 <= shifts.length <= 100000。

1 <= tasks[i] <= 1000000000。

1 <= shifts[i] <= 1000000000。

输入: tasks = [1,4,4], shifts = [9,1,4]。

输出: [0,2,1]。

解释:

班次 0:所有任务需要 1 + 4 + 4 = 9 单位时间,因此全部完成。未完成任务数量为 0。

班次 1:重新从任务 0 开始处理。该班次有 1 单位时间,因此任务 0 完成。未完成任务数量为 2。

班次 2:从任务 1 的当前位置继续处理。该班次有 4 单位时间,因此任务 1 完成。未完成任务数量为 1。

题目来自力扣4012。

详细过程如下:

1. 设任务数量为n,即tasks的长度。

  • 2. 将tasks原地转换为前缀和数组:

    • 转换后,tasks[i]表示前i+1个任务的总耗时。

  • • 例如原任务为[1,4,4],转换后为[1,5,9]。

  • • 这样tasks[n-1]就是所有任务的总耗时。

  • • 由于每个任务耗时都是正数,所以前缀和数组严格递增,适合二分查找。

    3. 初始化累计时间变量t = 0:

    •t表示从本轮第一个任务开始,到当前班次结束为止累计处理的工作时间。

  • • 如果还没有完成所有任务,t会持续累计到后续班次。

  • • 如果某一班次完成了所有任务,t会被重置为 0,表示下一班次从第一个任务重新开始。

    4. 按顺序遍历每一个班次shift:

    • 把当前班次可提供的时间加到累计时间中,即t增加当前shift。

  • • 此时t表示从本轮开始到当前班次结束,总共已经消耗的工作时间。

    5. 判断所有任务是否已经完成:

    • 如果t大于或等于所有任务总耗时,即t >= tasks[n-1],说明当前班次结束时所有任务已经完成。

  • • 按题意,如果班次内完成了所有任务,该班次立即结束,剩余时间作废,后续班次从第一个任务重新开始。

  • • 因此把t重置为 0。

  • • 当前班次结束后的未完成任务数为 0,所以把当前班次对应的结果写成 0。

    6. 如果所有任务还没有完成:

    • 需要在已经变成前缀和的tasks数组中,用二分查找找到第一个总耗时大于t的位置。

  • • 代码中查找的是第一个大于等于t+1的位置,因为所有耗时都是整数,这等价于找第一个前缀和大于t的任务位置。

  • • 设找到的位置为pos。

  • •pos的含义是:前pos个任务已经完整完成,因为前pos个任务的总耗时都不超过当前累计时间t。

  • • 从第pos个任务开始,后面的任务还没有完整完成。注意,第pos个任务可能正在处理但尚未完成,按题意也要计入未完成。

  • • 因此当前班次结束后的未完成任务数量为n - pos。

  • • 把这个数量写入当前班次对应的结果位置。

    7. 继续处理下一个班次:

    • 如果前面没有完成所有任务,t保持累计值,不重置,表示下一班次继续从当前未完成任务的位置往后处理。

  • • 如果前面完成了所有任务,t已经重置为 0,下一班次从第一个任务重新开始。

    8. 遍历结束后,shifts数组已经被原地覆盖为每个班次结束后的未完成任务数量,直接返回即可。

    以示例tasks = [1,4,4],shifts = [9,1,4]为例:

    • 先把tasks转换为前缀和:[1,5,9],总耗时为 9。

  • • 第 0 个班次时间为 9:

  • • 累计时间t = 0 + 9 = 9。

  • • 9 大于等于总耗时 9,说明所有任务完成。

  • • 未完成数为 0。

  • •t重置为 0。

  • • 第 1 个班次时间为 1:

  • • 累计时间t = 0 + 1 = 1。

  • • 1 小于总耗时 9。

  • • 在前缀和[1,5,9]中找第一个大于 1 的位置,得到位置 1。

  • • 说明前 1 个任务已经完成,剩下3 - 1 = 2个任务未完成。

  • • 结果为 2。

  • • 第 2 个班次时间为 4:

  • • 累计时间t = 1 + 4 = 5。

  • • 5 小于总耗时 9。

  • • 在前缀和[1,5,9]中找第一个大于 5 的位置,得到位置 2。

  • • 说明前 2 个任务已经完成,剩下3 - 2 = 1个任务未完成。

  • • 结果为 1。

  • • 最终结果为[0,2,1]。

    复杂度分析:

    • 总时间复杂度:
    前缀和计算需要遍历tasks一次,时间复杂度为O(n)。
    每个班次需要进行一次二分查找,二分查找时间复杂度为O(log n)。
    设shifts长度为m,则总时间复杂度为O(n + m log n)。

  • • 总额外空间复杂度:
    算法原地修改tasks为前缀和数组,并原地覆盖shifts作为结果数组。
    除少量变量外,二分查找为迭代实现,不需要额外数组。
    因此总额外空间复杂度为O(1)。

    Go完整代码如下:

    package main

    import (
    "fmt"
    "sort"
    )

    func countTasks(tasks, shifts []int) []int {
    n := len(tasks)
    // 原地计算 tasks 的前缀和
    for i := 1; i < n; i++ {
    tasks[i] += tasks[i-1]
    }

    t := 0
    for i, shift := range shifts {
    t += shift
    if t >= tasks[n-1] { // 完成所有任务
    t = 0
    shifts[i] = 0
    } else {
    shifts[i] = n - sort.SearchInts(tasks, t+1)
    }
    }
    return shifts
    }

    func main() {
    tasks := []int{1, 4, 4}
    shifts := []int{9, 1, 4}
    result := countTasks(tasks, shifts)
    fmt.Println(result)
    }

    2026-11-02:统计每个班次结束后的未完成任务数。用go语言,给定两个整数数组 tasks 和 shifts。tasks 中每个元素表示对应任务需要消耗的

    Python完整代码如下:

    # -*-coding:utf-8-*-

    import bisect

    def count_tasks(tasks, shifts):
    n = len(tasks)

    # 原地计算 tasks 的前缀和
    for i in range(1, n):
    tasks[i] += tasks[i - 1]

    t = 0
    for i, shift in enumerate(shifts):
    t += shift

    if t >= tasks[-1]: # 完成所有任务
    t = 0
    shifts[i] = 0
    else:
    idx = bisect.bisect_left(tasks, t + 1)
    shifts[i] = n - idx

    return shifts

    def main():
    tasks = [1, 4, 4]
    shifts = [9, 1, 4]

    result = count_tasks(tasks, shifts)
    print(result)

    if __name__ == "__main__":
    main()

    2026-11-02:统计每个班次结束后的未完成任务数。用go语言,给定两个整数数组 tasks 和 shifts。tasks 中每个元素表示对应任务需要消耗的

    C++完整代码如下:

      
    



    using namespace std;

    vector countTasks(vector tasks, vector shifts) {
    int n = tasks.size();

    // 原地计算 tasks 的前缀和
    for (int i = 1; i < n; i++) {
    tasks[i] += tasks[i - 1];
    }

    int t = 0;
    for (int i = 0; i < (int)shifts.size(); i++) {
    t += shifts[i];

    if (t >= tasks[n - 1]) { // 完成所有任务
    t = 0;
    shifts[i] = 0;
    } else {
    // 第一个 > t 的位置,等价于 Go 的 sort.SearchInts(tasks, t+1)
    int idx = upper_bound(tasks.begin(), tasks.end(), t) - tasks.begin();
    shifts[i] = n - idx;
    }
    }
    return shifts;
    }

    int main() {
    vector tasks = {1, 4, 4};
    vector shifts = {9, 1, 4};

    vector result = countTasks(tasks, shifts);

    cout << "[";
    for (int i = 0; i < (int)result.size(); i++) {
    if (i > 0) cout << ", ";
    cout << result[i];
    }
    cout << "]" << endl;

    return0;
    }

    2026-11-02:统计每个班次结束后的未完成任务数。用go语言,给定两个整数数组 tasks 和 shifts。tasks 中每个元素表示对应任务需要消耗的

    我们相信人工智能为普通人提供了一种“增强工具”,并致力于分享全方位的AI知识。在这里,您可以找到最新的AI科普文章、工具评测、提升效率的秘籍以及行业洞察。 欢迎关注“福大大架构师每日一题”,发消息可获得面试资料,让AI助力您的未来发展。

    © 版权声明

    相关文章