-
Notifications
You must be signed in to change notification settings - Fork 42
/
Copy pathProblem41.js
68 lines (60 loc) · 2.45 KB
/
Problem41.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
// Problem 41
//
// This problem was asked by Facebook.
//
// Given an unordered list of flights taken by someone, each represented as (origin, destination) pairs, and a starting airport, compute the person's itinerary.
// If no such itinerary exists, return null.
// If there are multiple possible itineraries, return the lexicographically smallest one. All flights must be used in the itinerary.
//
// For example, given the list of flights [('SFO', 'HKO'), ('YYZ', 'SFO'), ('YUL', 'YYZ'), ('HKO', 'ORD')] and starting airport 'YUL', you should return the list ['YUL', 'YYZ', 'SFO', 'HKO', 'ORD'].
//
// Given the list of flights [('SFO', 'COM'), ('COM', 'YYZ')] and starting airport 'COM', you should return null.
//
// Given the list of flights [('A', 'B'), ('A', 'C'), ('B', 'C'), ('C', 'A')] and starting airport 'A',
// you should return the list ['A', 'B', 'C', 'A', 'C'] even though ['A', 'C', 'A', 'B', 'C'] is also a valid itinerary. However, the first one is lexicographically smaller.
//
// https://leetcode.com/problems/reconstruct-itinerary/description/
//
// O(E log E) Time complexity
// O(E) Space Compleixty
// E is the number of edges for flights
import Heap from '../Data-Structures/Heap';
/**
* Returns the persons' itinerary
* @param {string[][]} flights
* @param {string} startingFlight
* @return {string[]?}
*/
function constructItinerary(flights, startingAirport) {
const flightsMap = new Map();
// maps origin to a priority queue of destination to keep the lexicographically order
for (let i = 0; i < flights.length; i++) {
const flight = flights[i];
const [origin, destination] = flight;
if (!flightsMap.has(origin))
flightsMap.set(origin, new Heap((a, b) => b.localeCompare(a)));
flightsMap.get(origin).add(destination);
}
const itinerary = [];
visit(startingAirport, flightsMap, itinerary);
const keys = Array.from(flightsMap.keys());
for (let i = 0; i < keys.length; i++) {
const pq = flightsMap.get(keys[i]);
if (pq.size() !== 0) return null;
}
return itinerary;
}
/**
* Perform dfs. When we are done visiting every neighbor in nodes, add to the front of itinerary
* @param {string} airport
* @param {Map<string, Heap>} flightsMap
* @param {string[]} itinerary
*/
function visit(airport, flightsMap, itinerary) {
const pq = flightsMap.get(airport);
if (pq !== undefined && pq.size() !== 0) {
visit(pq.poll(), flightsMap, itinerary);
}
itinerary.unshift(airport);
}
export default constructItinerary;