332. 重新安排行程

原题链接:332. 重新安排行程

solution:

有向图欧拉路径:

欧拉路径:经过每一条边一次,但是不要求回到起始点。

判断欧拉路径是否存在的方法

1.有向图 : 图连通,当且仅当该图所有顶点数的度数为0,或者一个顶点的度数为1,另一个顶点的度数为-1,其他顶点的度数为0.

2.无向图:图连通,当且仅当该图所有顶点的度数为偶数,或者除了两个度数为奇数外其余的全是偶数。

本题已经说明,一定有一条合法路径因此不需要判定是否有合法路径。下面以一张图表明什么是欧拉路径。

        该图的遍历顺序是:A-B-C-B-D-B-F,当抵达F也就是终点的时候,又有没有出度就会把F存入res答案中,并返回B继续遍历,B-E-B,最后返回B后由于B的所有出度都已遍历完就开始回溯。因此最后res = F-B-E-B-D-B-C-B-A,最后将res颠倒顺序即可。

        直接从起点开始dfs即可,每次选择一条没有遍历过的边,递归进行遍历。当把当前节点的所有出边都遍历完时,将该点加入路径序列。最终记录的路径是真正遍历路径的逆序,所以我们要将记录的路径逆序输出。题目中要求我们输出字典序最小的路径,直接贪心即可,每次优先选择字典序最小的出边进行遍历。这一步可以用堆或者平衡树来存储每个点的所有出边.

class Solution {
public:
    unordered_map<string,multiset<string>> g;   //存储有向图,同时可以起到去重和排序的作用
    vector<string> res; //返回值

    void dfs(string ver) {
        while(g[ver].size()) {
            auto next = *g[ver].begin(); //字典序最小的出路
            g[ver].erase(g[ver].begin());   //走过就删除本条路径
            dfs(next);
        }
        res.push_back(ver);
    }

    vector<string> findItinerary(vector<vector<string>>& tickets) {
        for (auto &ticket : tickets) g[ticket[0]].insert(ticket[1]);
        dfs("JFK");
        reverse(res.begin(),res.end());
        return res;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值