LeetCode 332 Reconstruct Itinerary
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
.
Note:
- 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"]
. - All airports are represented by three capital letters (IATA code).
- You may assume all tickets form at least one valid itinerary.
Example 1:tickets
= [["MUC", "LHR"], ["JFK", "MUC"], ["SFO", "SJC"], ["LHR", "SFO"]]
Return ["JFK", "MUC", "LHR", "SFO", "SJC"]
.
Example 2:tickets
= [["JFK","SFO"],["JFK","ATL"],["SFO","ATL"],["ATL","JFK"],["ATL","SFO"]]
Return ["JFK","ATL","JFK","SFO","ATL","SFO"]
.
Another possible reconstruction is ["JFK","SFO","ATL","JFK","ATL","SFO"]
. But it is larger in lexical order.
题目大意:
给定一组机票,用出发机场和到达机场[from, to]来表示,重建行程的顺序。所有的机票都属于一个从JFK(肯尼迪国际机场)出发的旅客。因此,行程必须从JFK开始。
注意:
如果存在多重有效的行程,你应当返回字典序最小的那个。例如,行程[“JFK”, “LGA”]的字典序比[“JFK”, “LGB”]要小。
所有的机场用3个大写字母表示(IATA编码)。
你可以假设所有的机票均至少包含一条有效的行程。
解题思路:
这条题实质是记录DFS路径的题目,且对儿子节点的选择是有顺序的。值得注意的是并不是所有路径都是可形成回路,所以需要DFS搜索。
既然是要记录路径就需要用数组保存结果,而有顺序则表示要排序。
- 建图,用邻接表来表示HashMap
> graph - 对每个节点的邻节点LinkList进行排序
- 从JFK开始dfs。1)终止条件为所有ticket都遍历了(达成回路)或者不能够遍历完。2)路径存在数组中。 3)通过删除节点表示已访问DFS该节点后图要恢复成原状态。
注意事项:
- 通过删除节点表示已访问DFS该节点后图要恢复成原状态。用下标i来删除,这样才能保证删除再加入仍然有序。另一种方法是用visited边来记录避免修改图。本文用前者
- 剪枝: 如果找到结果就返回
- 这题只有一条path,不是所有可能性,但让需要用res,复制path到res,因为path会恢复状态。
Python代码:
1 | def findItinerary2(self, tickets: List[List[str]]) -> List[str]: |
注意事项:
- 终止条件为所有ticket都遍历了(达成完整路)或者不能够遍历完Dfs API含ticketLeft。如{“JFK”,”KUL”},{“JFK”,”NRT”},{“NRT”,”JFK”},虽然KUL在NRT前,但KUL不能组成回路。
- DFS路径尽量存在数组中,否则用ArrayList中就要先add再remove。
- 通过删除节点表示已访问DFS该节点后图要恢复成原状态。
Java代码:
1 | public List<String> findItinerary(String[][] tickets) { |
算法分析:
时间复杂度为O(n)
,空间复杂度O(n)
。