You are given a list of airline tickets
where tickets[i] = [fromi, toi]
represent the departure and the arrival airports of one flight. Reconstruct the itinerary in order and return it.
All of the tickets belong to a man who departs from "JFK"
, thus, the itinerary must begin with "JFK"
. If there are multiple valid itineraries, you should return the itinerary that has the smallest lexical order when read as a single string.
- For example, the itinerary
["JFK", "LGA"]
has a smaller lexical order than["JFK", "LGB"]
.
You may assume all tickets form at least one valid itinerary. You must use all the tickets once and only once.
Example 1:
Input: tickets = [["MUC","LHR"],["JFK","MUC"],["SFO","SJC"],["LHR","SFO"]] Output: ["JFK","MUC","LHR","SFO","SJC"]
Example 2:
Input: tickets = [["JFK","SFO"],["JFK","ATL"],["SFO","ATL"],["ATL","JFK"],["ATL","SFO"]] Output: ["JFK","ATL","JFK","SFO","ATL","SFO"] Explanation: Another possible reconstruction is ["JFK","SFO","ATL","JFK","ATL","SFO"] but it is larger in lexical order.
Constraints:
1 <= tickets.length <= 300
tickets[i].length == 2
fromi.length == 3
toi.length == 3
fromi
andtoi
consist of uppercase English letters.fromi != toi
Companies:
Media.net, Facebook, Uber, Directi, Amazon, Google, Twilio, DoorDash, Walmart Labs
Related Topics:
Depth-First Search, Graph, Eulerian Circuit
Similar Questions:
For each node, try each neighbor node in ascending lexical order. The first path that reaches N + 1
nodes is the answer.
// OJ: https://leetcode.com/problems/reconstruct-itinerary/
// Author: github.com/lzl124631x
// Time: O(E^2)
// Space: O(E)
class Solution {
public:
vector<string> findItinerary(vector<vector<string>>& E) {
int N = E.size();
vector<bool> used(N);
unordered_map<string, vector<pair<string, int>>> G;
for (int i = 0; i < E.size(); ++i) G[E[i][0]].emplace_back(E[i][1], i);
for (auto &[u, vs] : G) sort(begin(vs), end(vs));
vector<string> path{"JFK"};
function<bool()> dfs = [&]() {
if (path.size() == N + 1) return true;
for (auto &[v, index] : G[path.back()]) {
if (used[index]) continue;
used[index] = true;
path.push_back(v);
if (dfs()) return true;
path.pop_back();
used[index] = false;
}
return false;
};
dfs();
return path;
}
};
// OJ: https://leetcode.com/problems/reconstruct-itinerary/
// Author: github.com/lzl124631x
// Time: O(E^2)
// Space: O(E)
// Ref: https://leetcode.com/problems/reconstruct-itinerary/discuss/78768/Short-Ruby-Python-Java-C%2B%2B
class Solution {
public:
vector<string> findItinerary(vector<vector<string>>& E) {
unordered_map<string, multiset<string>> G;
for (auto &e : E) G[e[0]].insert(e[1]);
vector<string> ans;
function<void(string)> euler = [&](string u) {
while (G[u].size()) {
auto v = *G[u].begin();
G[u].erase(G[u].begin());
euler(v);
}
ans.push_back(u);
};
euler("JFK");
return vector<string>(rbegin(ans), rend(ans));
}
};