A pizza restaurant receives n orders. For the i-th order:
- arr[i][0] represents the time at which the order is placed.
- arr[i][1] represents the time required to prepare the pizza.
Therefore, the delivery time of the i-th order is: arr[i][0] + arr[i][1]. Return the order numbers (1-based indexing) in the sequence in which customers receive their pizzas. If two or more orders are completed at the same time, they should be delivered in increasing order of their order numbers.
Examples:
Input: arr[] = [[4, 1], [6, 2], [7, 6], [8, 1], [1, 3]]
Output: [5, 1, 2, 4, 3]
Explanation: The completion times for the orders are [5, 8, 13, 9, 4]. Since the 5th order has the smallest completion time (4), it is delivered first, followed by the 1st (5), 2nd (8), 4th (9), and 3rd (13) orders. Hence, the required sequence is [5, 1, 2, 4, 3].Input: arr[] = [[1, 1], [1, 1], [1, 1]]
Output: [1, 2, 3]
Explanation: All three orders have the same completion time (1 + 1 = 2). Since orders completed at the same time are served in increasing order of their order numbers, the customers receive their pizzas in the order [1, 2, 3].
Table of Content
[Naive Approach] Repeatedly Find the Next Order O(n ^ 2) Time and O(n) Space
The idea is to compute the completion time for every order. Then, repeatedly scan all unfinished orders to find the one with the smallest completion time. If multiple orders finish at the same time, choose the one with the smaller order number.
Working of Approach:
- Compute the completion time for every order.
- Maintain a visited array to mark processed orders.
- Repeatedly scan all unprocessed orders to find the minimum completion time.
- If two orders have the same completion time, choose the smaller order number.
- Add the selected order to the answer and mark it as visited.
#include <bits/stdc++.h>
using namespace std;
// Function to return the order in which customers receive their pizzas
vector<int> customerOrder(vector<vector<int>> &arr)
{
int n = arr.size();
vector<int> completion(n);
vector<bool> vis(n, false);
vector<int> res;
// Compute the completion time for every order
for (int i = 0; i < n; i++)
completion[i] = arr[i][0] + arr[i][1];
// Select one order in each iteration
for (int cnt = 0; cnt < n; cnt++)
{
int idx = -1;
// Find the unfinished order with the minimum completion time
for (int i = 0; i < n; i++)
{
if (vis[i])
continue;
if (idx == -1 || completion[i] < completion[idx] || (completion[i] == completion[idx] && i < idx))
{
idx = i;
}
}
// Mark the selected order as processed
vis[idx] = true;
// Store its order number
res.push_back(idx + 1);
}
return res;
}
int main()
{
vector<vector<int>> arr = {{4, 1}, {6, 2}, {7, 6}, {8, 1}, {1, 3}};
vector<int> res = customerOrder(arr);
cout << "[";
for (int i = 0; i < res.size(); i++)
{
cout << res[i];
if (i != res.size() - 1)
cout << ", ";
}
cout << "]";
return 0;
}
import java.util.*;
public class GFG {
// Function to return the order in which customers
// receive their pizzas
static ArrayList<Integer> customerOrder(int[][] arr)
{
int n = arr.length;
int[] completion = new int[n];
boolean[] vis = new boolean[n];
ArrayList<Integer> res = new ArrayList<>();
// Compute the completion time for every order
for (int i = 0; i < n; i++)
completion[i] = arr[i][0] + arr[i][1];
// Select one order in each iteration
for (int cnt = 0; cnt < n; cnt++) {
int idx = -1;
// Find the unfinished order with the minimum
// completion time
for (int i = 0; i < n; i++) {
if (vis[i])
continue;
if (idx == -1
|| completion[i] < completion[idx]
|| (completion[i] == completion[idx]
&& i < idx)) {
idx = i;
}
}
// Mark the selected order as processed
vis[idx] = true;
// Store its order number
res.add(idx + 1);
}
return res;
}
public static void main(String[] args)
{
int[][] arr = {
{ 4, 1 }, { 6, 2 }, { 7, 6 }, { 8, 1 }, { 1, 3 }
};
ArrayList<Integer> res = customerOrder(arr);
System.out.print("[");
for (int i = 0; i < res.size(); i++) {
System.out.print(res.get(i));
if (i != res.size() - 1)
System.out.print(", ");
}
System.out.print("]");
}
}
def customerOrder(arr):
# Function to return the order in which customers receive their pizzas
n = len(arr)
completion = [0] * n
vis = [False] * n
res = []
# Compute the completion time for every order
for i in range(n):
completion[i] = arr[i][0] + arr[i][1]
# Select one order in each iteration
for cnt in range(n):
idx = -1
# Find the unfinished order with the minimum completion time
for i in range(n):
if vis[i]:
continue
if idx == -1 or completion[i] < completion[idx] or (completion[i] == completion[idx] and i < idx):
idx = i
# Mark the selected order as processed
vis[idx] = True
# Store its order number
res.append(idx + 1)
return res
if __name__ == "__main__":
arr = [[4, 1], [6, 2], [7, 6], [8, 1], [1, 3]]
res = customerOrder(arr)
print("[", end="")
for i in range(len(res)):
print(res[i], end="")
if i != len(res) - 1:
print(", ", end="")
print("]")
using System;
using System.Collections.Generic;
class GFG {
// Function to return the order in which customers
// receive their pizzas
static List<int> customerOrder(int[, ] arr)
{
int n = arr.GetLength(0);
int[] completion = new int[n];
bool[] vis = new bool[n];
List<int> res = new List<int>();
// Compute the completion time for every order
for (int i = 0; i < n; i++)
completion[i] = arr[i, 0] + arr[i, 1];
// Select one order in each iteration
for (int cnt = 0; cnt < n; cnt++) {
int idx = -1;
// Find the unfinished order with the minimum
// completion time
for (int i = 0; i < n; i++) {
if (vis[i])
continue;
if (idx == -1
|| completion[i] < completion[idx]
|| (completion[i] == completion[idx]
&& i < idx)) {
idx = i;
}
}
// Mark the selected order as processed
vis[idx] = true;
// Store its order number
res.Add(idx + 1);
}
return res;
}
static void Main()
{
int[, ] arr = {
{ 4, 1 }, { 6, 2 }, { 7, 6 }, { 8, 1 }, { 1, 3 }
};
List<int> res = customerOrder(arr);
Console.Write("[");
for (int i = 0; i < res.Count; i++) {
Console.Write(res[i]);
if (i != res.Count - 1)
Console.Write(", ");
}
Console.Write("]");
}
}
function customerOrder(arr)
{
// Function to return the order in which customers
// receive their pizzas
let n = arr.length;
let completion = new Array(n).fill(0);
let vis = new Array(n).fill(false);
let res = [];
// Compute the completion time for every order
for (let i = 0; i < n; i++) {
completion[i] = arr[i][0] + arr[i][1];
}
// Select one order in each iteration
for (let cnt = 0; cnt < n; cnt++) {
let idx = -1;
// Find the unfinished order with the minimum
// completion time
for (let i = 0; i < n; i++) {
if (vis[i])
continue;
if (idx == -1 || completion[i] < completion[idx]
|| (completion[i] == completion[idx]
&& i < idx)) {
idx = i;
}
}
// Mark the selected order as processed
vis[idx] = true;
// Store its order number
res.push(idx + 1);
}
return res;
}
// Driver Code
let arr =
[ [ 4, 1 ], [ 6, 2 ], [ 7, 6 ], [ 8, 1 ], [ 1, 3 ] ];
let res = customerOrder(arr);
console.log("[");
for (let i = 0; i < res.length; i++) {
process.stdout.write(res[i].toString());
if (i != res.length - 1)
process.stdout.write(", ");
}
console.log("]");
Output
[5, 1, 2, 4, 3]
[Expected Approach] Sort Orders by Completion Time O(n log n) Time and O(n) Space
The idea is to compute the completion time for every order and store it along with its order number. Sort all orders by completion time. If two orders finish at the same time, the smaller order number comes first automatically.
Working of Approach:
- Compute the completion time for every order.
- Store (completion time, order number) for each order.
- Sort the list of pairs.
- Since pairs are sorted lexicographically, ties are resolved using the order number.
- Traverse the sorted list and collect the order numbers.
Let us understand with an example:
Input: arr[] = [[4, 1], [6, 2], [7, 6], [8, 1], [1, 3]]
- Compute the completion time for each order and store (completion time, order number) as: [(5, 1), (8, 2), (13, 3), (9, 4), (4, 5)].
- Sort these pairs by completion time. If two completion times are equal, the smaller order number comes first automatically.
- After sorting, the pairs become: [(4, 5), (5, 1), (8, 2), (9, 4), (13, 3)].
- Traverse the sorted pairs and collect the order numbers.
- The final delivery sequence is [5, 1, 2, 4, 3].
#include <bits/stdc++.h>
using namespace std;
vector<int> customerOrder(vector<vector<int>> &arr)
{
int n = arr.size();
vector<pair<int, int>> v;
// Store completion time and order number
for (int i = 0; i < n; i++)
{
v.push_back({arr[i][0] + arr[i][1], i + 1});
}
// Sort by completion time, and by order number in case of a tie
sort(v.begin(), v.end());
vector<int> res;
// Store the required order of customers
for (int i = 0; i < n; i++)
{
res.push_back(v[i].second);
}
return res;
}
int main()
{
vector<vector<int>> arr = {{4, 1}, {6, 2}, {7, 6}, {8, 1}, {1, 3}};
vector<int> res = customerOrder(arr);
cout << "[";
for (int i = 0; i < res.size(); i++)
{
cout << res[i];
if (i != res.size() - 1)
cout << ", ";
}
cout << "]";
return 0;
}
import java.util.*;
public class GFG {
// Function to return the order in which customers
// receive their pizzas
static ArrayList<Integer> customerOrder(int[][] arr)
{
int n = arr.length;
ArrayList<int[]> v = new ArrayList<>();
// Store completion time and order number
for (int i = 0; i < n; i++) {
v.add(
new int[] { arr[i][0] + arr[i][1], i + 1 });
}
// Sort by completion time, and by order number in
// case of a tie
Collections.sort(v, (a, b) -> {
if (a[0] != b[0])
return a[0] - b[0];
return a[1] - b[1];
});
ArrayList<Integer> res = new ArrayList<>();
// Store the required order of customers
for (int i = 0; i < n; i++) {
res.add(v.get(i)[1]);
}
return res;
}
public static void main(String[] args)
{
int[][] arr = {
{ 4, 1 }, { 6, 2 }, { 7, 6 }, { 8, 1 }, { 1, 3 }
};
ArrayList<Integer> res = customerOrder(arr);
System.out.print("[");
for (int i = 0; i < res.size(); i++) {
System.out.print(res.get(i));
if (i != res.size() - 1)
System.out.print(", ");
}
System.out.print("]");
}
}
def customerOrder(arr):
n = len(arr)
v = []
# Store completion time and order number
for i in range(n):
v.append((arr[i][0] + arr[i][1], i + 1))
# Sort by completion time, and by order number in case of a tie
v.sort()
res = []
# Store the required order of customers
for i in range(n):
res.append(v[i][1])
return res
if __name__ == "__main__":
arr = [[4, 1], [6, 2], [7, 6], [8, 1], [1, 3]]
res = customerOrder(arr)
print("[", end="")
for i in range(len(res)):
print(res[i], end="")
if i != len(res) - 1:
print(", ", end="")
print("]")
using System;
using System.Collections.Generic;
class GFG {
// Function to return the order in which customers
// receive their pizzas
static List<int> customerOrder(int[, ] arr)
{
int n = arr.GetLength(0);
List<Tuple<int, int> > v
= new List<Tuple<int, int> >();
// Store completion time and order number
for (int i = 0; i < n; i++) {
v.Add(
Tuple.Create(arr[i, 0] + arr[i, 1], i + 1));
}
// Sort by completion time, and by order number in
// case of a tie
v.Sort((a, b) = > {
if (a.Item1 != b.Item1)
return a.Item1.CompareTo(b.Item1);
return a.Item2.CompareTo(b.Item2);
});
List<int> res = new List<int>();
// Store the required order of customers
for (int i = 0; i < n; i++) {
res.Add(v[i].Item2);
}
return res;
}
static void Main()
{
int[, ] arr = {
{ 4, 1 }, { 6, 2 }, { 7, 6 }, { 8, 1 }, { 1, 3 }
};
List<int> res = customerOrder(arr);
Console.Write("[");
for (int i = 0; i < res.Count; i++) {
Console.Write(res[i]);
if (i != res.Count - 1)
Console.Write(", ");
}
Console.Write("]");
}
}
function customerOrder(arr)
{
const n = arr.length;
let v = [];
// Store completion time and order number
for (let i = 0; i < n; i++) {
v.push([ arr[i][0] + arr[i][1], i + 1 ]);
}
// Sort by completion time, and by order number in case
// of a tie
v.sort((a, b) => a[0] - b[0] || a[1] - b[1]);
let res = [];
// Store the required order of customers
for (let i = 0; i < n; i++) {
res.push(v[i][1]);
}
return res;
}
// Driver Code
const arr =
[ [ 4, 1 ], [ 6, 2 ], [ 7, 6 ], [ 8, 1 ], [ 1, 3 ] ];
const res = customerOrder(arr);
console.log("[" + res.join(", ") + "]");
Output
[5, 1, 2, 4, 3]