Leetcode-Algorithm-Graph-332
-
题目:
-
Given a list of airline tickets represented by pairs of departure and arrival airports
[from,to]
, reconstruct the itinerary in order. All of the tickets belong to a man who departs from
JFK
, Thus, the itinerary must begin with
JFK
.
(给定一个飞机票的列表,通过起始机场[from, to]来表示。根据机票列表重新构造出整个旅行路线。所有机票都是属于一个从JFK出发的人的,因此旅程必须是从JFK开始的。)
注意:
- 若存在多个旅行路线,按照字典序返回最小的那一个。
例子:
给定:tickets = [[“MUC”, “LHR”], [“JFK”, “MUC”], [“SFO”, “SJC”], [“LHR”, “SFO”]].
返回:[“JFK”, “MUC”, “LHR”, “SFO”, “SJC”].
给定:tickets = [[“JFK”,”SFO”],[“JFK”,”ATL”],[“SFO”,”ATL”],[“ATL”,”JFK”],[“ATL”,”SFO”]].
返回:[“JFK”,”ATL”,”JFK”,”SFO”,”ATL”,”SFO”].
(这个例子中另一条路线是[“JFK”,”SFO”,”ATL”,”JFK”,”ATL”,”SFO”],但是由于字典序的关系,返回的是[“JFK”,”ATL”,”JFK”,”SFO”,”ATL”,”SFO”]。)
题解:
方法:(DFS-深度优先搜索)
根据题意,需要通过飞机票确定旅行路线,所以每一张飞机票都需要使用。因此,若以机场为顶点,机票为机场间的有向边,我们可以构造出一个有向图,而问题就转换为找到一条路径能够经过所有的边一次且仅一次,也相当于找到有向图中字典序最小的一条欧拉路径。因此我们在构造一个图的时候必须记录每一条边,通过测试用例知道会存在重复的边,因此需要记录边的数目以便确定是否已经遍历完所有的边。所以代码中使用unordered_map以及map的组合来记录所有变,由于map中元素是根据key来排序的,因此同时满足我们需要根据字典序来遍历的需求。构造好图后通过DFS来遍历整个图,记录DFS在通过某条路径走到最后时(即遍历的下一条边之前已经遍历过)是否都经过所有的边,不是,返回上一层从别的路径开始遍历,是,则返回到顶层递归。在遍历的过程中一直记录着路径中的所有顶点。
class Solution {
public:
vector<string> findItinerary(vector<pair<string, string>> tickets) {
unordered_map<string, map<string, int>> graph;
//通过unordered_map以及map的组合记录每一张机票代表的边。
//因为最后的路线要按照字典序,因此在构图时就需要按字典序排好。
for (auto ticket : tickets) {
graph[ticket.first][ticket.second] += 1;
}
vector<string> result;
result.push_back("JFK");
int count = 0;
traverse(graph, result, "JFK", count, tickets.size());
return result;
}
//通过DFS来遍历整个图,在遍历过程中记录以遍历的边的数量以此为
//是否需要继续遍历的标准并作相应的处理。
void traverse(unordered_map<string, map<string, int>> &graph,
vector<string> &result,
string org, int &count, int full) {
map<string, int>::iterator iter = graph[org].begin();
while (iter != graph[org].end()) {
string des = iter->first;
int linkCount = iter->second;
if (linkCount != 0) {
iter->second -= 1;
result.push_back(des);
traverse(graph, result, des, ++count, full);
if (count == full)
break;
else {
result.pop_back();
--count;
iter->second += 1;
}
}
++iter;
}
}
};