Quay lại danh sách thử thách
Trung bình 0 đã giải Tỷ lệ chấp nhận 0%

Thứ tự hoàn thành tác vụ song song

Chạy các task đồng thời với tối đa k task cùng lúc và báo cáo thứ tự chúng hoàn thành.

Bạn sẽ học được gì

  • Chạy tác vụ với giới hạn song song
  • Mô phỏng thời gian bằng hàng đợi ưu tiên
  • Phân định các tác vụ xong cùng lúc

Đề bài

Xem bản gốc (English)

Với async/await bạn có thể khởi động nhiều task và để chúng chạy cùng lúc. Một SemaphoreSlim thường giới hạn số task được chạy đồng thời.

Các task được đánh số từ 0 đến n − 1 và mất durations[i] đơn vị thời gian. Tại thời điểm 0, hãy bắt đầu càng nhiều task càng tốt theo giới hạn, theo thứ tự chỉ số. Mỗi khi task hoàn thành, ghi nhận nó (nếu nhiều task hoàn thành cùng lúc thì chỉ số nhỏ hơn trước) và ngay lập tức bắt đầu các task chờ tiếp theo, theo thứ tự chỉ số, để lấp đầy các vị trí trống.

Implement parallel_task_order(durations, limit).

Input

durations: Thời gian mỗi task mất.

limit: Số task tối đa có thể chạy cùng lúc.

Output

Trả về các chỉ số task theo thứ tự chúng hoàn thành.

Ràng buộc

1 ≤ n ≤ 100,000

1 ≤ durations[i] ≤ 10^6; 1 ≤ limit ≤ n

Ví dụ

Ví dụ 1
Đầu vào:
limit = 2
durations = [4, 2, 3, 1]

Kết quả mong đợi:
expected = [1, 0, 2, 3]
Đầu vào:
long long limit = 2;
std::vector<long long> durations = {4, 2, 3, 1};

Kết quả mong đợi:
std::vector<long long> expected = {1, 0, 2, 3};
Đầu vào:
long limit = 2;
long[] durations = new long[] {4, 2, 3, 1};

Kết quả mong đợi:
long[] expected = new long[] {1, 0, 2, 3};

Giải thích

Các task 0 và 1 bắt đầu. Task 1 kết thúc tại 2 và task 2 bắt đầu (kết thúc tại 5). Task 0 kết thúc tại 4 và task 3 bắt đầu (kết thúc tại 5). Tasks 2 và 3 hoàn thành cùng lúc, chỉ số nhỏ hơn trước: [1, 0, 2, 3].

Ví dụ 2
Đầu vào:
limit = 3
durations = [3, 1, 2]

Kết quả mong đợi:
expected = [1, 2, 0]
Đầu vào:
long long limit = 3;
std::vector<long long> durations = {3, 1, 2};

Kết quả mong đợi:
std::vector<long long> expected = {1, 2, 0};
Đầu vào:
long limit = 3;
long[] durations = new long[] {3, 1, 2};

Kết quả mong đợi:
long[] expected = new long[] {1, 2, 0};

Giải thích

Tất cả tasks chạy cùng lúc và hoàn thành tại 1, 2 và 3: [1, 2, 0].

Hướng tiếp cận

Hãy tự thử trước, sau đó mở từng gợi ý một.

Gợi ý 1

Giữ các tác vụ đang chạy theo thứ tự thời điểm xong, rồi theo chỉ số.

Gợi ý 2

Mỗi bước nhảy tới thời điểm xong kế tiếp và lấy mọi tác vụ kết thúc lúc đó.

Gợi ý 3

Lấp chỗ trống bằng các tác vụ đang chờ kế tiếp theo thứ tự chỉ số.

Độ phức tạp mong đợi

thời gian O(n log limit), bộ nhớ phụ O(limit)

Tham khảo

Thử thách này đã được điều chỉnh cho CodeUtility. Hãy làm theo đề bài và các ràng buộc ở trên.

Học hỏi từ người khác

Giải pháp cộng đồng

Chưa có giải pháp nào được chia sẻ. Hãy giải thử thách này để đăng giải pháp đầu tiên.