(未完成)332. Reconstruct Itinerary

本文介绍了一种基于深度优先搜索(DFS)的算法,用于解决给定一系列机票后如何按顺序规划行程的问题。该算法确保从JFK出发并遵循字典序最小原则。通过将边而非节点作为访问对象,并利用DFS进行递归探索,最终实现行程的有效重建。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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.

s思路:
1. 给两两连接的机场,要求得到一整条路线。仔细观察,还是图的遍历嘛,但又不同与之前看到的图的遍历,因为之前的遍历是考虑节点是否被访问,而这里则是边是否被访问。这一点一定要先搞明白。如下图,从JFK开始,有两个邻居,ATL和SFO,先访问哪个题目有规定,字典排序小的机场先访问,所以先访问ATL,由于是找路线,自然是用dfs最方便,访问了ATL,常规的做法是需要标记已经访问过,但这里只需要使用一次这条边,所以干脆直接删除这条边,就不用标记是否访问,然后到ATL继续遍历,发现也有两个邻居JFK,SFO,这里也是一样,西安访问JFK,同时把JFK这条边删除;现在到JFK后,发现JFK只有一个邻居SFO(ATL已经被删除),于是访问SFO,同时删除SFO这条链接;继续遍历SFO的邻居,发现有ATL,于是访问ATL,同时删除ATL这条边,现在到ATL发现也只有一个邻居SFO,于是继续访问SFO,同时删除链接,到SFO发现没有邻居了,意味着结束了吗?还是需要回到上一层继续遍历呢?保险起见,是需要回到上一层吧!
这里写图片描述
2.由于要字典顺序访问,所以最好对每个节点的邻居排序,所以不用vector放邻居,而用map.
3. 上面分析还是不对,debug的时候,发现前面分析的不对呀,没有反应过来,所谓图里面元素的排序,本质就是topological sort,先用dfs走一边,谁的邻居节点都遍历完谁就先放入vector,最好等所有节点都放入vector再reverse vector即可!由于不是检测是否有环,所以仍然不需要用visited来表示一个节点是否访问完全还是正在访问,

class Solution {
public:

    void dfs(unordered_map<string,set<string>>&mm,vector<string>&res,string cur){
        if(mm.count(cur)==0) return;    
        for(auto it=mm[cur].begin();it!=mm[cur].end();)
        for(auto&str:mm[cur]){
            string next=str;
            mm[cur].erase(str);
            res.push_back(next);
            dfs(mm,res,next);
        }
    }   

    vector<string> findItinerary(vector<pair<string, string>> tickets) {
        //
        unordered_map<string,set<string>> mm;
        for(auto&t:tickets){
            mm[t.first].insert(t.second);        
        }
        vector<string> res;
        dfs(mm,res,"JFK");
        return res;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值