题目关键词:
- 按字符自然排序返回
- 每个机票只能用一次
隐含信息
- 可能给出多张相同机票(可能成环)
1 回溯法(新数据结构)
本题除了欧拉回路方法外,还可使用回溯法,但需要依据已有多个基础数据结构组合成新数据结构,新数据结构具体要求如下
[1] 实现一对多映射——multimap满足
[2] 一个key可映射到多个相同value——multimap满足
[3] 按key值排序(升序)——map/multimap满足
[4] 可在迭代器循环中频繁进行增删改查——不能直接对容器元素插入删除,可额外开辟计数器实现
【新数据结构】:unordered_map<出发城市, map<到达城市, 相同到达城市计数器>>
【例子】:[["MUC", "LHR"], ["MUC", "LHR"], ["LHR", "SFO"]]
map["MUC"]["LHR"] = 2
map["LHR"]["SFO"] = 1
【额外注意】:
- 每个key对应value的个数不同,无法统一设定上限,但可以统一设定下限,故先-后+
- 题目输出只要一个解,而非解的集合,因此是
bool backtrack()
而非void backtrack()
有了上面例子,就好理解了。废话不多说,完整代码如下
class Solution {
private:
/**
题目要求的新数据结构需满足条件:
[1]实现一对多映射——multimap满足
[2]一个key可映射到多个相同value——multimap满足
[3]按key值排序(升序)——map/multimap满足
[4]可在迭代器循环中频繁进行增删改查——不能直接对容器元素插入删除,可额外开辟计数器实现
新数据结构:unordered_map<string, map<string, int>>
**/
unordered_map<string, map<string, int>> str2map;
vector<string> solution;
int size;
public:
bool backtrack(map<string, int>& str2int) {
if (solution.size() == size + 1) return true;
for (auto& map : str2int) {
if (map.second <= 0) continue;
solution.emplace_back(map.first);
// 每个key对应value的个数不同,无法统一设定上限,但可以统一设定下限,故先-后+
map.second --;
if (backtrack(str2map[map.first])) return true;
map.second ++;
solution.pop_back();
}
return false;
}
vector<string> findItinerary(vector<vector<string>>& tickets) {
size = tickets.size();
for (auto& vec : tickets)
str2map[vec[0]][vec[1]] ++;
// 在回溯前插入JFK是因为backtrack应该接受选择列表参数, 故最好的方式是传入str2map["JFK"]
solution.emplace_back("JFK");
backtrack(str2map["JFK"]);
return solution;
}
};