1882. Process Tasks Using Servers - Explanation

Problem Link



1. Brute Force (Simulation)

class Solution:
    def assignTasks(self, servers: List[int], tasks: List[int]) -> List[int]:
        n, m = len(servers), len(tasks)
        available = [True] * n
        finishTime = [0] * n
        res = []
        time = 0

        for t in range(m):
            time = max(time, t)

            for i in range(n):
                if finishTime[i] <= time:
                    available[i] = True

            if not any(available):
                time = min(finishTime)
                for i in range(n):
                    if finishTime[i] <= time:
                        available[i] = True

            minIdx = -1
            for i in range(n):
                if (available[i] and
                    (minIdx == -1 or servers[i] < servers[minIdx] or
                    (servers[i] == servers[minIdx] and i < minIdx))
                ):
                    minIdx = i

            res.append(minIdx)
            available[minIdx] = False
            finishTime[minIdx] = time + tasks[t]

        return res

Time & Space Complexity

  • Time complexity: O(mn)O(m * n)
  • Space complexity:
    • O(n)O(n) extra space.
    • O(m)O(m) space for the output array.

Where mm is the number of tasks and nn is the number of servers.


2. Two Min-Heaps - I

class Solution:
    def assignTasks(self, servers: List[int], tasks: List[int]) -> List[int]:
        res = [0] * len(tasks)
        available = [(servers[i], i) for i in range(len(servers))]
        heapq.heapify(available)
        unavailable = []

        t = 0
        for i in range(len(tasks)):
            t = max(t, i)

            if not available:
                t = unavailable[0][0]

            while unavailable and t >= unavailable[0][0]:
                timeFree, weight, index = heapq.heappop(unavailable)
                heapq.heappush(available, (weight, index))

            weight, index = heapq.heappop(available)
            res[i] = index
            heapq.heappush(unavailable, (t + tasks[i], weight, index))

        return res

Time & Space Complexity

  • Time complexity: O((n+m)logn)O((n + m) \log n)
  • Space complexity:
    • O(n)O(n) extra space.
    • O(m)O(m) space for the output array.

Where mm is the number of tasks and nn is the number of servers.


3. Two Min-Heaps - II

class Solution:
    def assignTasks(self, servers: List[int], tasks: List[int]) -> List[int]:
        res = []
        available = [[weight, i, 0] for i, weight in enumerate(servers)]
        unavailable = []
        heapq.heapify(available)

        for i, task in enumerate(tasks):
            while unavailable and unavailable[0][0] <= i or not available:
                timeFree, weight, index = heapq.heappop(unavailable)
                heapq.heappush(available, [weight, index, timeFree])

            weight, index, timeFree = heapq.heappop(available)
            res.append(index)
            heapq.heappush(unavailable, [max(timeFree, i) + task, weight, index])

        return res

Time & Space Complexity

  • Time complexity: O((n+m)logn)O((n + m) \log n)
  • Space complexity:
    • O(n)O(n) extra space.
    • O(m)O(m) space for the output array.

Where mm is the number of tasks and nn is the number of servers.