AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / coding / 问题 / 79379217
Accepted
CodeCrusader
CodeCrusader
Asked: 2025-01-23 05:09:04 +0800 CST2025-01-23 05:09:04 +0800 CST 2025-01-23 05:09:04 +0800 CST

给定任务,程序员在更短的时间内解决任务

  • 772

我有一个大小为的任务列表n,处理所需的时间表示为tasks[i],其中i是任务的索引。

处理步骤:i = 0这些任务应按从到的顺序i = n-1一个接一个地进行处理。

现在有另一个大小为 的程序员列表m,他们可以在 所表示的指定时间内完成任务programmers[i],其中i是索引。

如果任务的值为 0,则表示任务已完成,否则该任务为待处理任务。

因此,如果上述处理步骤结束时仍有一些任务待处理,则处理应从到重新i = 0开始i = n-1

如果所有任务都完成了,那么我们可以重新加载任务并从头开始处理。

我想收集每个程序员在指定的时间内工作后仍有多少任务处于待处理状态。

以下是一个例子:

示例 1

n=5,任务= [2, 4, 5, 1, 1] m=5,程序员=[1, 5, 1, 5, 2]

程序员 任务 待处理任务
1 [1, 4, 5, 1, 1] 第一项任务已部分处理,总待处理任务数 = 5
2 [0, 0, 5, 1, 1] 前两个任务已全部处理完毕,总待处理任务数 = 3
3 [0, 0, 4, 1, 1] 第三项任务已部分处理,总待处理任务数 = 3
4 [0, 0, 0, 0, 1] 第三和第四个任务已全部处理完毕,总待处理任务数 = 1
5 [0, 0, 0, 0, 0] 最后一项任务已全部处理完毕,待处理任务总数 = 0

因此,待处理任务的数量 =[5, 3, 3, 1, 0]

示例 2

任务 =[1, 2, 4, 1, 2] 程序员 =[3, 10, 1, 1, 1]

程序员 任务 待处理任务
1 [0, 0, 4, 1, 2] 第一和第二个任务已全部处理完毕,总待处理任务数 = 3
2 [0, 0, 0, 0, 0] 所有任务均已完全处理,待处理任务总数 = 0(待处理任务为 0,因此加载回所有任务[1,2,4,1,2])
3 [0, 2, 4, 1, 2] 第一个任务已完全处理,总待处理任务数 = 4
4 [0, 1, 4, 1, 2] 第二项任务已部分处理,待处理任务总数 = 4
5 [0, 0, 3, 1, 2] 第二项任务已全部处理完毕,待处理任务总数 = 3

输出 =[3,0,4,4,3]

示例 3

任务 =[1, 4, 4] 程序员 =[9, 1, 4]

输出 =[0, 2, 1]

以下是我在 O(m*n) 时间内运行的代码:

import java.util.*;

public class Main {

    public static List<Integer> getPendingTasks(List<Integer> tasks, List<Integer> programmers) {
        List<Integer> pendingTasks = new ArrayList<>();
        List<Integer> originalTasks = new ArrayList<>(tasks); // Save original tasks for reloading
        int n = tasks.size();
        
        for (int programmer : programmers) {
            int timeRemaining = programmer;
            for (int i = 0; i < n && timeRemaining > 0; i++) {
                if (tasks.get(i) > 0) {
                    if (tasks.get(i) <= timeRemaining) {
                        timeRemaining -= tasks.get(i);
                        tasks.set(i, 0);
                    } else {
                        tasks.set(i, tasks.get(i) - timeRemaining);
                        timeRemaining = 0;
                    }
                }
            }

            // Count pending tasks
            int pending = 0;
            for (int task : tasks) {
                if (task > 0) {
                    pending++;
                }
            }

            pendingTasks.add(pending);

            // Reload tasks if all are completed
            if (pending == 0) {
                tasks = new ArrayList<>(originalTasks);
            }
        }

        return pendingTasks;
    }

    public static void main(String[] args) {
        // Example 1
        List<Integer> tasks1 = Arrays.asList(2, 4, 5, 1, 1);
        List<Integer> programmers1 = Arrays.asList(1, 5, 1, 5, 2);
        System.out.println("Output: " + getPendingTasks(tasks1, programmers1)); // Output: [5, 3, 3, 1, 0]

        // Example 2
        List<Integer> tasks2 = Arrays.asList(1, 2, 4, 1, 2);
        List<Integer> programmers2 = Arrays.asList(3, 10, 1, 1, 1);
        System.out.println("Output: " + getPendingTasks(tasks2, programmers2)); // Output: [3, 0, 4, 4, 3]

        // Example 3
        List<Integer> tasks3 = Arrays.asList(1, 4, 4);
        List<Integer> programmers3 = Arrays.asList(9, 1, 4);
        System.out.println("Output: " + getPendingTasks(tasks3, programmers3)); // Output: [0, 2, 1]
    }
}

我还尝试使用 PriorityQueue 仅处理待处理的任务:

import java.util.*;

class Main {

    public static List<Integer> getPendingTasks(List<Integer> tasks, List<Integer> programmer) {
        List<Integer> result = new ArrayList<>();
        Queue<Integer> pending = new PriorityQueue<>();
        int n = tasks.size();
        List<Integer> originalTasks = new ArrayList<>(tasks);

        // Initialize set with all tasks
        for (int i = 0; i < n; i++) {
            pending.add(i);
        }
        Queue<Integer> q = new PriorityQueue<>(pending);
        
        // Process each item
        for (int p : programmer) {
            int timeAvailable = p;

            // Process only unprocessed tasks
            List<Integer> balancedTask = new ArrayList<>();
            
            while (!q.isEmpty()) {
                int i = q.poll();
                if (tasks.get(i) <= timeAvailable) {
                    timeAvailable -= tasks.get(i);
                    // Task fully processed
                } else {
                    tasks.set(i, tasks.get(i) - timeAvailable); // Partially processed
                    timeAvailable = 0; // time exhausted
                    balancedTask.add(i);
                }
            }
            q.addAll(balancedTask);
            result.add(q.size());
            if(q.size() ==0) {
                tasks = originalTasks;
                q= pending;
            }
        }

        return result;
    }

    public static void main(String[] args) {
        System.out.println(getPendingTasks(Arrays.asList(2, 4, 5, 1, 1), Arrays.asList(1, 5, 1, 5, 2))); 
        // Expected: [5, 3, 3, 1, 0]
        
        System.out.println(getPendingTasks(Arrays.asList(1, 2, 4, 1, 2), Arrays.asList(3, 10, 1, 1, 1))); 
        // Expected: [3, 0, 4, 4, 3]
        
        System.out.println(getPendingTasks(Arrays.asList(1, 4, 4), Arrays.asList(9, 1, 4))); 
        // Expected: [0, 2, 1]
    }
}

但是上面的代码也会在O(n*m*log(m))时间复杂度上运行

限制:

n and m in range 1 to 2 * 10^5
each item in input lists is 1 to 10^9

我想知道如何在较少的时间复杂度内解决这个问题

java
  • 1 1 个回答
  • 79 Views

1 个回答

  • Voted
  1. Best Answer
    Unmitigated
    2025-01-23T09:55:10+08:002025-01-23T09:55:10+08:00

    我们可以计算任务持续时间的前缀和数组,然后在每次迭代中进行二分搜索,找到第一个总任务持续时间大于当前程序员可以完成的工作量的点(时间复杂度为O(m log n))。

    public static List<Integer> getPendingTasks(List<Integer> tasks, List<Integer> programmers) {
        var res = new ArrayList<Integer>(programmers.size());
        var sum = new long[tasks.size() + 1];
        for (int i = 1; i <= tasks.size(); i++) sum[i] = sum[i - 1] + tasks.get(i - 1);
        int prev = 0;
        long extra = 0;
        for (int work : programmers) {
            if (work >= sum[tasks.size()] - sum[prev] + extra) {
                res.add(0);
                extra = prev = 0;
                continue;
            }
            int low = prev, high = tasks.size();
            while (low <= high) {
                int mid = low + high >>> 1;
                if (sum[mid] - sum[prev] + extra > work) high = mid - 1;
                else low = mid + 1;
            }
            extra = sum[low] - sum[prev] + extra - work;
            prev = low;
            res.add(tasks.size() - low + (extra > 0 ? 1 : 0));
        }
        return res;
    }
    
    • 2

相关问题

  • Lock Condition.notify 抛出 java.lang.IllegalMonitorStateException

  • 多对一微服务响应未出现在邮递员中

  • 自定义 SpringBoot Bean 验证

  • Java 套接字是 FIFO 的吗?

  • 为什么不可能/不鼓励在服务器端定义请求超时?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    重新格式化数字,在固定位置插入分隔符

    • 6 个回答
  • Marko Smith

    为什么 C++20 概念会导致循环约束错误,而老式的 SFINAE 不会?

    • 2 个回答
  • Marko Smith

    VScode 自动卸载扩展的问题(Material 主题)

    • 2 个回答
  • Marko Smith

    Vue 3:创建时出错“预期标识符但发现‘导入’”[重复]

    • 1 个回答
  • Marko Smith

    具有指定基础类型但没有枚举器的“枚举类”的用途是什么?

    • 1 个回答
  • Marko Smith

    如何修复未手动导入的模块的 MODULE_NOT_FOUND 错误?

    • 6 个回答
  • Marko Smith

    `(表达式,左值) = 右值` 在 C 或 C++ 中是有效的赋值吗?为什么有些编译器会接受/拒绝它?

    • 3 个回答
  • Marko Smith

    在 C++ 中,一个不执行任何操作的空程序需要 204KB 的堆,但在 C 中则不需要

    • 1 个回答
  • Marko Smith

    PowerBI 目前与 BigQuery 不兼容:Simba 驱动程序与 Windows 更新有关

    • 2 个回答
  • Marko Smith

    AdMob:MobileAds.initialize() - 对于某些设备,“java.lang.Integer 无法转换为 java.lang.String”

    • 1 个回答
  • Martin Hope
    Fantastic Mr Fox msvc std::vector 实现中仅不接受可复制类型 2025-04-23 06:40:49 +0800 CST
  • Martin Hope
    Howard Hinnant 使用 chrono 查找下一个工作日 2025-04-21 08:30:25 +0800 CST
  • Martin Hope
    Fedor 构造函数的成员初始化程序可以包含另一个成员的初始化吗? 2025-04-15 01:01:44 +0800 CST
  • Martin Hope
    Petr Filipský 为什么 C++20 概念会导致循环约束错误,而老式的 SFINAE 不会? 2025-03-23 21:39:40 +0800 CST
  • Martin Hope
    Catskul C++20 是否进行了更改,允许从已知绑定数组“type(&)[N]”转换为未知绑定数组“type(&)[]”? 2025-03-04 06:57:53 +0800 CST
  • Martin Hope
    Stefan Pochmann 为什么 {2,3,10} 和 {x,3,10} (x=2) 的顺序不同? 2025-01-13 23:24:07 +0800 CST
  • Martin Hope
    Chad Feller 在 5.2 版中,bash 条件语句中的 [[ .. ]] 中的分号现在是可选的吗? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench 为什么双破折号 (--) 会导致此 MariaDB 子句评估为 true? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng 为什么 `dict(id=1, **{'id': 2})` 有时会引发 `KeyError: 'id'` 而不是 TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob:MobileAds.initialize() - 对于某些设备,“java.lang.Integer 无法转换为 java.lang.String” 2024-03-20 03:12:31 +0800 CST

热门标签

python javascript c++ c# java typescript sql reactjs html

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve