Amazon Interview Question
Country: United States
This question is very similar to the "Merge Intervals" question. Sharing my solution in Python below.
Order Class
class Order:
def __init__(self, orderID, items):
self.orderID = orderID
self.items = items
def __repr__(self):
return '{}->Items{}'.format(self.orderID, self.items)
Group Orders Function
def groupOrders(orders):
# First sort the items so that we can optimally merge them
orders.sort(key=lambda o: o.items)
res = [orders[0]]
# Iterate through the orders
for currentOrder in orders[1:]:
# Represents the overlap / commonality between two orders
# If overlap is found, then merge them and create a new order with the union of them
# Else, simply append it to the end of the array.
foundMerge = False
for ind2, groupedOrder in enumerate(res):
overlap = set(currentOrder.items) & set(groupedOrder.items)
if overlap:
# If the orderId is already a list, just append, ex:- [O1, O2], O3 -> [O1, O2, O3]
if type(groupedOrder.orderID) is list:
groupedOrder.orderID.append(currentOrder.orderID)
else: # If not a list, create a new list, ex:- O1, O2 -> [O1, O2]
groupedOrder.orderID = [groupedOrder.orderID , currentOrder.orderID]
res[ind2] = Order( groupedOrder.orderID ,
set(currentOrder.items) | set(groupedOrder.items) )
foundMerge = True
break
# If there was no overlap, simply append at the end of the array
if not foundMerge:
res.append(currentOrder)
# Return only the orderID as the output
return [x.orderID for x in res]
Test Code
orders = [ Order('O1', ['A', 'B']) ,
Order('O2', ['C', 'D'])]
print(groupOrders(orders)) # ['O1', 'O2']
orders = [ Order('O1', ['A', 'B']) ,
Order('O2', ['A', 'D'])]
print(groupOrders(orders)) # [['O1', 'O2']]
orders = [ Order('O1', ['A', 'B']) ,
Order('O2', ['B', 'C']),
Order('O3', ['D', 'E']) ]
print(groupOrders(orders)) # [['O1', 'O2'], 'O3']
orders = [ Order('O1', ['A', 'B']) ,
Order('O2', ['C', 'D']),
Order('O3', ['E', 'F']) ]
print(groupOrders(orders)) # ['O1', 'O2', 'O3']
orders = [ Order('O1', ['A', 'B']) ,
Order('O2', ['A', 'D']),
Order('O3', ['A', 'E']) ]
print(groupOrders(orders)) # [['O1', 'O2', 'O3']]
//With a test
public class App {
static class Order {
int id;
List<String> items;
public Order(int id, List<String> items) {
this.id = id;
this.items = items;
}
}
public static void main(String[] args) {
List<Order> orders = new ArrayList<>();
List<String> l1 = new ArrayList<>();
List<String> l2 = new ArrayList<>();
List<String> l3 = new ArrayList<>();
l1.add("A");
l1.add("B");
l2.add("B");
l2.add("C");
l3.add("K");
l3.add("P");
l3.add("L");
l3.add("A");
orders.add(new Order(1, l1));
orders.add(new Order(2, l2));
orders.add(new Order(3, l3));
Map<String, List<Integer>> maps = new HashMap<>();
orders.forEach(order -> {
order.items.forEach(item -> {
maps.putIfAbsent(item, new ArrayList<>());
maps.get(item).add(order.id);
});
});
maps.entrySet().stream().forEach(item -> {
System.out.println(item.getKey()+":"+item.getValue());
});
}
}
use connected component approache
- muesmat September 19, 2018