Leetcode 332. Reconstruct Itinerary[medium]

题目:
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.


这个题就是求欧拉路,即一笔画问题。
欧拉路的算法简单而巧妙,就是一遍dfs。其中记录路径是用栈记录的,而且入栈是在dfs函数执行之后。这巧妙的规避了在x点dfs可能第一次找的路径是无法回到x点的问题。
如果还是不能理解的话,我给出一组数据就很好理解了:

int main() {
    Solution s;
    vector< pair<string, string> > t;
    t.push_back(make_pair("JFK","KUL"));
    t.push_back(make_pair("JFK","NRT"));
    t.push_back(make_pair("NRT","JFK"));
    vector<string> r;
    r = s.findItinerary(t);
    for (int i = 0; i < r.size(); i++)
        cout << r[i] << "   ";
    return 0;
}

这里写图片描述

class Solution {
public:
    #define N 2222
    map<string, int> mp;
    int cnt;
    vector<string> edg[N];
    stack<string> stk; 
    vector<string> ans;
    vector<bool> vis[N];
    vector<string> findItinerary(vector< pair<string, string> > tickets) {
        mp.clear();
        ans.clear();
        for (int i = 0; i < N; i++) {
            edg[i].clear();
            vis[i].clear();
        }
        cnt = 0;

        for (int i = 0; i < tickets.size(); i++) {
            if (mp[tickets[i].first] == 0) {
                mp[tickets[i].first] = ++cnt;
            }
            if (mp[tickets[i].second] == 0) {
                mp[tickets[i].second] = ++cnt;
            }
            edg[mp[tickets[i].first]].push_back(tickets[i].second);
            vis[mp[tickets[i].first]].push_back(false);
        } 
        for (int i = 1; i <= cnt; i++)
            sort(edg[i].begin(), edg[i].end());
        dfs("JFK");
        stk.push("JFK");
        while (stk.size()) {
            ans.push_back(stk.top());
            stk.pop();
        }

        return ans;
    }

    void dfs(string str) {
        int x = mp[str];
        for (int i = 0; i < edg[x].size(); i++) 
            if (vis[x][i] == false) {
                vis[x][i] = true;
                dfs(edg[x][i]);
                stk.push(edg[x][i]);
            }
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值