文章目录
- 重新安排行程
- 思路一
重新安排行程
给你一份航线列表 tickets ,其中 tickets[i] = [fromi, toi] 表示飞机出发和降落的机场地点。请你对该行程进行重新规划排序。
所有这些机票都属于一个从 JFK(肯尼迪国际机场)出发的先生,所以该行程必须从 JFK 开始。如果存在多种有效的行程,请你按字典排序返回最小的行程组合。
例如,行程 [“JFK”, “LGA”] 与 [“JFK”, “LGB”] 相比就更小,排序更靠前。
假定所有机票至少存在一种合理的行程。且所有的机票 必须都用一次 且 只能用一次。
图一:
图二:
示例 1:图一
输入:tickets = [["MUC","LHR"],["JFK","MUC"],["SFO","SJC"],["LHR","SFO"]]
输出:["JFK","MUC","LHR","SFO","SJC"]
示例 2:图二
输入:tickets = [["JFK","SFO"],["JFK","ATL"],["SFO","ATL"],["ATL","JFK"],["ATL","SFO"]]
输出:["JFK","ATL","JFK","SFO","ATL","SFO"]
解释:另一种有效的行程是 ["JFK","SFO","ATL","JFK","ATL","SFO"] ,但是它字典排序更大更靠后。
思路一
function findItinerary(tickets) {
const flights = {};
tickets.forEach(ticket => {
if (!flights[ticket[0]]) {
flights[ticket[0]] = [];
}
flights[ticket[0]].push(ticket[1]);
});
// 对每个机场的目的地进行排序,以确保字典序最小的路径
Object.keys(flights).forEach(key => {
flights[key].sort();
});
const itinerary = [];
function dfs(airport) {
while (flights[airport] && flights[airport].length > 0) {
const next = flights[airport].shift();
dfs(next);
}
itinerary.unshift(airport);
}
dfs("JFK");
return itinerary;
}
讲解
因为这是一个图论中的欧拉路径问题。我们需要找到从“JFK”机场出发,遍历所有机票且不重复的路径。这实际上是一个深度优先搜索(DFS)的问题,需要构建一个图,并从“JFK”开始进行搜索,同时保持路径的字典序最小。
- 构建图:使用一个Map来存储从每个机场出发的所有航班,Map的key是机场名称,value是一个按照字典序排序的机场列表,表示从该机场可以飞往的所有机场。
- 深度优先搜索(DFS):从“JFK”开始,递归地进行DFS。在每次递归调用中,我们选择下一个机场,将其从可用的航班中移除,并将该机场添加到路径中。当没有更多的航班可选时,递归返回。
- 回溯:在DFS中,当回溯时,我们需要恢复之前的状态,即将选择的航班重新放回可用航班列表中。
- 构建结果:在DFS的过程中,不断构建结果路径。由于我们按照字典序排序,所以最先找到的路径将是字典序最小的路径。