算法练习(13) —— Reconstruct Itinerary

算法练习(13) —— Reconstruct Itinerary

习题

本题取自 leetcode 中的 Graph 栏目中的第241题:
Reconstruct Itinerary


题目如下:

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

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.

Example1

tickets = [[“MUC”, “LHR”], [“JFK”, “MUC”], [“SFO”, “SJC”], [“LHR”, “SFO”]]

Return [“JFK”, “MUC”, “LHR”, “SFO”, “SJC”].

Example2

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.

思路与代码

  • 首先理解题意,有若干个对,里面存储起点和终点。要求算出从地点”JFK”出发,有序的路线。并且如果有分岔路的话,要按字典序排序。
  • 因为需要排序,所以很容易想到STL的map函数,既能很方便的重新记录数据,又能执行排序操作。
  • 因为可能会有起点相同或者终点相同的对,因此如果想用set作为map的value即第二个参数,可能会丢失数据。因此这里采用之前函数中用到的multiset,允许内部元素重复
  • 至于算法,用一个dfs即可解决~

代码如下:

#include <vector>
#include <string>
#include <map>
#include <set>

using namespace std;

class Solution {
private:
    map<string, multiset <string> > path;           // every point's can-go path
    vector<string> route;                           // route
public:
    vector<string> findItinerary(vector<pair<string, string>> tickets) {
        // reconstruct by using map func
        for (auto t : tickets)
            path[t.first].insert(t.second);

        // start point must be "JFK"
        visit("JFK");

        // reverse the route as the result
        return vector<string>(route.rbegin(), route.rend());
    }

    // dfs visit
    void visit(string tar) {
        while (!path[tar].empty()) {
            string next = *path[tar].begin();
            path[tar].erase(path[tar].begin());
            visit(next);
        }
        route.push_back(tar);
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值