【算法】【Graph】Reconstruct Itinerary

Difficulty: Medium

Description

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:

  1. 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"].

  2. All airports are represented by three capital letters (IATA code).

  3. 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.

Solution

思路

一开始我以为是简单的DFS算法,但发现Submission怎样都无法通过。后来才知道,原来题中“valid itinerary”是指,这个人所有的tickets必须连成一条完整的线,类似于一笔画,但首尾不一定要相连。

那该怎么完成这个一笔画呢。一个简单的解决办法是用后序遍历,再把遍历的这些地点倒序输出,即完成。

拿Discuss高票回答的例子来说,若输出[JFK, A, C, D, A, B, C, JFK, D]则是错误的,因为这不能连成一笔画,这个人不可能从A凭空消失,出现在D并继续飞往B的。

<code>[JFK, A], [A, C], [C, D], [D, A], [D, B], [B, C], [C, JFK], [JFK, D]</code>

正确的做法之一是,先后拓展了[JFK, A, C, D, A]后,发现没路了,写出A(push进vector<string> out 中,此时out中的元素为[A]),回到D,再依次进入[B, C, JFK, D],没路了,写出D,回到JFK,发现也没路了,写出JFK,如此类推。

最后out = [A, D, JFK, C, B, D, C, A, JFK]。返回倒序的out数组,完成。

代码

class Solution {
public:
    vector<string> findItinerary(vector<pair<string, string>> tickets) {
        for (auto t : tickets) {
            route[t.first].insert(t.second);
        }
        dfs("JFK");
        return vector<string>(output.rbegin(), output.rend());

    }

private:
    unordered_map<string, multiset<string>> route;
    vector<string> output;

    void dfs(string src) {
        while (route[src].size()) {
            auto p = route[src].begin();
            string dst = *p;
            route[src].erase(p);
            dfs(dst);
        }
        output.push_back(src);
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值