It can be done faster, in O(n) time, if the constraints on start and finish time is low. We can make a dp array, in which for each job, we will do dp[job[i].start]+=1 and dp[job[i].end+1]-=1. After calcualting prefix array from it, maximum number will be our answer. This question is very much similar to the minimum number of lecture halls. For more details, you can refer https://www.geeksforgeeks.org/minimum-halls-required-for-class-scheduling/.
Answer from Vivek on Stack OverflowI guess you are missing the cases, where there are multiple jobs starting in the same time and all of them could be completed before the next job starts which is very small.
For example,
5
0 3
0 2
0 4
10 2
10 1
should enqeue first 3 items and process all of them before enqeuing other 2 items. This case will fail in your case.
Other observation:
The for loop for arranging the vector based in cooktime is not needed and coded wrongly.
for(long long i=0;i<n-1;i++)
{
if(c[i].arrTime==c[i+1].arrTime && c[i].cookTime>c[i].cookTime)
{
swap(c[i],c[i+1]);
}
}
It must be 'c[i].cookTime>c[i+1].cookTime' The priority queue ensure that you get the least cooktime from given set
A working solution passing all cases written in python is given below for reference.
import heapq
def getAvgWaitTime(n, cust):
heap = []
curTime = 0
waitTime = 0
cust = sorted(cust)
i = 0
while i < n:
if curTime < cust[i][0]:
curTime = cust[i][0]
while i < n and (curTime >= cust[i][0]):
heapq.heappush(heap, (cust[i][1], cust[i][0]))
i += 1
while (i < n) and curTime < cust[i][0] and len(heap) > 0:
time, wait = calculateWaiting(heap, curTime)
curTime += time
waitTime += wait
# Clear all the jobs
while len(heap) > 0:
time, wait = calculateWaiting(heap, curTime)
curTime += time
waitTime += wait
return waitTime / n
def calculateWaiting(heap, curTime):
wait = 0
cur = heapq.heappop(heap)
wait = curTime - cur[1] + cur[0]
return (cur[0], wait)
n = int(raw_input().strip())
cust = []
for i in range(n):
ar = map(int, raw_input().strip().split(' '))
cust.append((ar[0], ar[1]))
result = getAvgWaitTime(n, cust)
print result
Hope it helps!
Explanation
First, a short explanation on important aspects of the problem.
- Orders may not come in the right order, meaning they may not be sorted by arrival time. So, make sure to sort them by arrival time first.
- It's important to realise that out of waiting orders, the cook must pick the one with the minimum cooking time. This way, the resulting waiting time will always be minimal.
- Additionally, if there are no orders for the cook to process, the "current" time can be played out till the next arriving order.
Code
In addition to the accepted answer, a C++ solution (since the question is marked with a C++ tag) may look as below.
#include <bits/stdc++.h>
using namespace std;
struct customer {
uint64_t arrivalTime;
uint64_t cookingTime;
};
/*
* Complete the minimumAverage function below.
*/
uint64_t minimumAverage(std::deque<customer> clients, uint32_t numberOfClients) {
auto compareByArrivalTime =
{
return client1.arrivalTime < client2.arrivalTime;
};
auto compareByCookingTime =
{
return client1.cookingTime > client2.cookingTime;
};
std::sort(clients.begin(), clients.end(), compareByArrivalTime);
std::priority_queue<customer, std::vector<customer>, decltype(compareByCookingTime)> clientPriorityQueue(compareByCookingTime);
uint64_t minWaitingTime = 0;
uint64_t currentTime = clients.front().arrivalTime;
for (auto servedClient = 1; servedClient <= numberOfClients; servedClient++) {
while (!clients.empty() && currentTime >= clients.front().arrivalTime) {
clientPriorityQueue.push(clients.front());
clients.pop_front();
}
customer bestClient = clientPriorityQueue.top();
clientPriorityQueue.pop();
uint64_t arrivalTime = bestClient.arrivalTime;
uint64_t cookingTime = bestClient.cookingTime;
minWaitingTime += (currentTime - arrivalTime + cookingTime);
currentTime += cookingTime;
if (!clients.empty()) {
currentTime = std::max(currentTime, clients.front().arrivalTime);
}
}
return minWaitingTime / numberOfClients;
}
int main()
{
uint32_t n;
std::cin >> n;
std::deque<customer> clients;
for (auto i = 0; i < n; i++) {
customer client;
std::cin >> client.arrivalTime >> client.cookingTime;
clients.push_back(client);
}
uint64_t result = minimumAverage(clients, n);
std::cout << result << "\n";
return 0;
}