题目
题解
这道题的几个难点:
- 一个行程中,如果航班处理不好容易变成一个圈,成为死循环
- 有多种解法,字母序靠前排在前面,应该如何记录映射关系?
- 使用回溯法,终止条件是什么?
- 搜索的过程中,如何遍历一个机场所对应的所有机场?
如何理解死循环
如图情况,若没有处理好,可能在JFK和NRT之间形成死循环
如何记录映射关系
一个机场映射多个机场,机场之间要靠字母序排列,可以使用HashMap记录
定义如下:
Map<String,Map<String, Integer>>map:Map<出发机场,Map<到达机场,航班次数>>map
为什么一定要增删元素呢?因为出发机场和到达机场会重复,搜索的过程没及时删除目的机场就会死循环。
在遍历Map<出发机场,Map<到达机场,航班次数>>map
过程中,可以使用“航班次数”这个字段做加减,来标记到达机场是否使用过了。
如果“航班次数”大于0,说明目的地还可以飞,如果“航班次数”等于0说明目的地不能飞了,而不用对集合做删除元素或者增加元素的操作。(相当于说我不删,我就做一个标记!)
回溯法
递归树
回溯三部曲
- 递归函数参数
使用Map<出发机场,Map<到达机场,航班次数>>map
记录航班的映射关系
注意这里函数返回值是boolean!而不是通常用的void!
因为我们只需要找到一个行程,就是在树形结构中唯一一条通向叶子节点的路线,如上递归树所示。
- 递归终止条件
回溯过程中遇到的机场个数,达到了(航班数量+1),就找到了一个行程,将所有航班串在一起了。
if(res.size()==n+1){
return;
}
- 单层搜索过程
回溯的过程中,如何遍历一个机场所对应的所有机场呢?
for (pair<const string, int>& target : targets