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;
}
};
头疼还没好 以后再继续深究。。。