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"]。
但是它自然排序更大更靠后。
普通的DFS,并且要求对到达机场进行排序
这题说明了一个好的数据结构是多么的重要,学到不少
首先排序的过程用 ,而 对 排序时默认第一维升序,一维相同的情况下对二维升序,所以我们不用自己再写一个 了
其次就是在dfs过程中访问下一个结点时怎么寻找下一个节点及其所带的信息,因为结点信息是字符串,邻接表不好搞,所以就想map了,有重复,那么就用
既然键值有重复,那么[]是肯定不能用了,插入用 ,其中元素的值是一个有序对,其中第一个组件相当于键值,第二个组件相当于该元素的数据值
查找键值的时候用 (元素的键与指定值匹配的元素范围)
返回一对迭代器 ,其中第一个是键的 ,第二个是键的
dfs也要返回bool来判断是否成功,失败的话才能取消标记
class Solution
{
private:
using paii = pair<string, bool>;
int used = 0;//用过的机票
vector<string> ans;
multimap<string, paii> m;
bool dfs(string city)
{
if (m.size() == used)//所用的机票都已经用过
return true;
auto range = m.equal_range(city);//range为键city的范围
for (auto it = range.first; it != range.second; ++it)
{
if (it->second.second == false)//当前机票没有用过
{
it->second.second = true;
++used;
ans.push_back(it->second.first);
if (dfs(it->second.first))//深搜可以走下去
return true;
it->second.second = false;
--used;
ans.pop_back();
}
}
return false;
}
public:
vector<string> findItinerary(vector<pair<string, string>> tickets)
{
sort(tickets.begin(), tickets.end());
//第一维是出发机场,二维是目的地以及判断这张机票是否被用过
for (auto it = tickets.begin(); it != tickets.end(); ++it)
m.insert(make_pair(it->first, make_pair(it->second, false)));
ans.push_back("JFK");
dfs("JFK");
return ans;
}
};