题目描述
原题链接:332. 重新安排行程
解题思路
本题要解决的问题:
- 需要构建起始与目的机场的映射关系;
- 每次选择目的机场时,需要选择当前最小字母顺序的机场;
- 从
“JFK”
之后依次飞往,并且可能会有多条路径。
解决方法:
- 构建一个Hash表,但同一个起始机场可能会有多个目的机场,Key为string,Value可设置为一个按序排列的哈希表,同时还可以保证value修改为0时,这个Key-Value关系还存在。因此选择Value的结构为
map<string, int>
,int表示是否飞往过飞机场。而不选择multiset<string>
的原因,是因为当把这个减为0时,该key-value关系就会消失。 - backtracking返回值设为
bool
,当找到一条路径会返回。没找到时,以递归的方式去遍历下一个机场,完成后再以回溯的方式去遍历下一种情况。
class Solution {
public:
// 因一个起始机场可能会对应多个目标机场,因此value设为map<string, int>可便于按从小到达排序记录和修改是否飞过
// key:标记起始机场,value:其中的string表示降落机场,int表示是未飞过,飞过为0,未飞过为1
unordered_map<string, map<string, int>> record;
bool backtracking(int ticketNum, vector<string>& res) {
// 机场个数+1 = 飞行路径段数
if(res.size() == ticketNum + 1) return true;
// 每次从结果的最后一个起始机场,找可选择的目标机场
for(pair<const string, int>& target : record[res[res.size() - 1]]) {
if(target.second > 0) { // 当未从起始机场飞到过目的机场时
res.push_back(target.first); // 加入目的机场
target.second--; // 已飞到,减一
// 向下遍历下一个飞行地点,若已经飞完,则可直接剪枝
if(backtracking(ticketNum, res)) return true;
target.second++; // 再遍历从起始机场飞往其余目的机场的情况
res.pop_back();
}
}
return false;
}
vector<string> findItinerary(vector<vector<string>>& tickets) {
vector<string> res;
// 完成key-value的映射
for(const vector<string>& ticket : tickets) {
record[ticket[0]][ticket[1]]++;
}
res.push_back("JFK");
backtracking(tickets.size(), res);
return res;
}
};
使用const
、&
与vector
、string
搭配原因:
报错:non-const lvalue reference to type 'basic_str…cannot bind to a temporary…:不能对临时变量加引用、const与vector的搭配、C++ 容器vector等中为什么尽量使用const引用
参考文章:332.重新安排行程