c++
class Solution {
public:
vector<string> findItinerary(vector<pair<string, string>> tickets) {
if (tickets.empty()) return vector<string>();
unordered_map<string, multiset<string>> graph;
for (auto &v : tickets) {
graph[v.first].insert(v.second);
}
stack<string> dfs;
dfs.push("JFK");
vector<string> res;
while (!dfs.empty()){
string cur_node = dfs.top();
if (graph[cur_node].empty()) {
res.push_back(cur_node);
dfs.pop();
}
else {
dfs.push(*graph[cur_node].begin());
graph[cur_node].erase(graph[cur_node].begin());
}
}
reverse(res.begin(), res.end());
return res;
}
};
python
class Solution(object):
def findItinerary(self, tickets):
"""
:type tickets: List[List[str]]
:rtype: List[str]
"""
if not tickets: return []
graph = collections.defaultdict(list)
for a, b in sorted(tickets)[::-1]:
graph[a].append(b)
dfs = ['JFK']
res = []
while dfs:
cur_node = dfs[-1]
if not graph[cur_node]:
res.append(dfs.pop())
else:
dfs.append(graph[cur_node].pop())
return res[::-1]
reference:
1\ https://leetcode.com/discuss/85439/short-iterative-solution-explanation-recursive-backtracking
2\ Introduction to Algorithms, Chapter 22: Graph Algorithms