(83)332. 重新安排行程(leetcode)*

332. 重新安排行程
	给定一个机票的字符串二维数组 [from, to],子数组中的两个成员分别表示飞机出发和降落的机场地点,
	对该行程进行重新规划排序。所有这些机票都属于一个从 JFK(肯尼迪国际机场)出发的先生,
	所以该行程必须从 JFK 开始。
说明:
	如果存在多种有效的行程,你可以按字符自然排序返回最小的行程组合。
	例如,行程 ["JFK", "LGA"] 与 ["JFK", "LGB"] 相比就更小,排序更靠前
	所有的机场都用三个大写字母表示(机场代码)。
	假定所有机票至少存在一种合理的行程。
示例 1:
	输入: [["MUC", "LHR"], ["JFK", "MUC"], ["SFO", "SJC"], ["LHR", "SFO"]]
	输出: ["JFK", "MUC", "LHR", "SFO", "SJC"]
示例 2:
	输入: [["JFK","SFO"],["JFK","ATL"],["SFO","ATL"],["ATL","JFK"],["ATL","SFO"]]
	输出: ["JFK","ATL","JFK","SFO","ATL","SFO"]
	解释: 另一种有效的行程是 ["JFK","SFO","ATL","JFK","ATL","SFO"]。但是它自然排序更大更靠后。

没有思路 不会做啊。。。
欧拉回路 要不是看见题解的解释我都忘记还有这么一个东西了 Hierholzer 算法 嗯 第一次听说。。。

	有向且连通  求欧拉路径
Hierholzer 算法过程:
	选择任一顶点为起点,遍历所有相邻边。深度搜索,访问相邻顶点。将经过的边都删除。
	如果当前顶点没有相邻边,则将顶点入栈。
	栈中的顶点倒序输出,就是从起点出发的欧拉回路。

不过题解中针对题目做出了一个改变
当遍历完一个节点所连的所有节点后,我们才将该节点入栈,即逆序入栈。(nb啊)
这样可以保证序列不会进入死胡同。

    bbb<——>jfk ——> aaa
    
	如果jfk先进入aaa 那么就陷入了死胡同  无法再继续 
	若我们逆序入栈  1. 枚举jfk的相邻结点  2. dfs(当前结点)  
	3.  结束后 在对jfk入栈     
	若 当前结点是 非死胡同  那么在枚举当前结点 递归时 会再次会到jfk结点
	若 当前结点是 死胡同  那么在枚举当前结点时 它会首个入栈

对于序列顺序问题 使用priority_queue进行排序 dfs时就可以保证顺序

class Solution {
    
    
public:
    unordered_map<string, priority_queue<string, vector<string>, std::greater<string>>> vec;
    vector<string> ans;

    void dfs(const string& cur) {
    
    
        while(vec.count(cur)&&vec[cur].size()>0){
    
    
            string tmp=vec[cur].top();
            vec[cur].pop();
            dfs(move(tmp));
        }
        ans.emplace_back(cur);
    }
    vector<string> findItinerary(vector<vector<string>>& tickets) {
    
    
        for(auto &it:tickets){
    
    
            vec[it[0]].emplace(it[1]);
        }
        dfs("JFK");
        reverse(ans.begin(),ans.end());
        return ans;
    }
};

头疼还没好 以后再继续深究。。。

猜你喜欢

转载自blog.csdn.net/li_qw_er/article/details/108261230