本文记录的是刷题过程中的重要概念和笔记。如有侵权,请联系删除。

目录

  • 332.重新安排行程
  • 思路
    • 死循环
    • 记录映射关系
  • 回溯法
  • c++
    • 补充:const
  • 总结

332.重新安排行程

力扣题目链接(opens new window)

给定一个机票的字符串二维数组 [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”]。但是它自然排序更大更靠后。

思路

难点:
航班成为死循环
有多种解法,字母序靠前排在前面;如何该记录映射关系呢 ?
使用回溯法(也可以说深搜) 的话,那么终止条件是什么呢?
搜索的过程中,如何遍历一个机场所对应的所有机场。

死循环

出发机场和到达机场也会重复的,如果在解题的过程中没有对集合元素处理好,就会死循环。

记录映射关系

一个机场映射多个机场,机场之间要靠字母序排列,一个机场映射多个机场,可以使用std::unordered_map,如果让多个机场之间再有顺序的话,就是用std::map 或者std::multimap 或者 std::multiset。

unordered_map<string, multiset> targets:unordered_map<出发机场, 到达机场的集合>
targets

unordered_map<string, map<string, int>> targets:unordered_map<出发机场,
map<到达机场, 航班次数>> targets

这两个结构,我选择了后者,因为如果使用unordered_map<string, multiset> targets 遍历multiset的时候,不能删除元素,一旦删除元素,迭代器就失效了。可以使用"航班次数"这个字段的数字做相应的增减,来标记到达机场是否使用过了。

再说一下为什么一定要增删元素呢,出发机场和到达机场是会重复的,搜索的过程没及时删除目的机场就会死循环。

回溯法

函数返回值我用的是bool!
因为我们只需要找到一个行程,就是在树形结构中唯一的一条通向叶子节点的路线

终止条件是:遇到的机场个数,如果达到了(航班数量+1),那么我们就找到了一个行程,把所有航班串在一起了。

c++

class Solution
{public:// unordered_map<出发机场, map<到达机场, 航班次数>> targetsunordered_map<string, map<string, int>> targets;vector<string> res;bool backtracing(int ticketNum){if (ticketNum + 1 == res.size()){return true;}for (auto &target : targets[res[res.size() - 1]]){// 必须加上&,否则只是按值传递,虽然在循环中变值,出来又没变// auto& : pair<const string,int>&   targets[res[res.size()-1]]的元素类型if (target.second > 0)// 记录到达机场是否飞过了{res.push_back(target.first);target.second--;if (backtracing(ticketNum))return true;target.second++;res.pop_back();}}return false;}vector<string> findItinerary(vector<vector<string>> &tickets){targets.clear();res.clear();for (auto ticket : tickets){// 没有改变ticket的值,所以可以不加上&// auto :vector<string> ->  const vector<string>&targets[ticket[0]][ticket[1]]++;// 记录映射关系}res.push_back("JFK");// 起始机场backtracing(tickets.size());return res;}
};

代码中

for (pair<const string, int>& target : targets[result[result.size() - 1]])
pair里要有const,因为map中的key是不可修改的,所以是pair<const string, int>。
&这时是要有的,不然是按值传递

如果不加const,也可以复制一份pair,例如这么写:
for (pair<string, int>target : targets[result[result.size() - 1]])

补充:const

在 C++ 中,const 关键字用于声明一个常量。它可以应用于变量、函数参数、函数返回值和成员函数。
将 const 应用于变量时,表示该变量的值是不能被修改的
将 const 应用于函数参数时,表示该参数在函数中是只读的,不能修改其值。
将 const 应用于函数返回值时,表示该返回值是只读的
将 const 应用于成员函数时,表示该函数不会修改对象的状态

总结

如果单纯的回溯搜索(深搜)并不难,难还难在容器的选择和使用上。

本题其实是一道深度优先搜索的题目,但是我完全使用回溯法的思路来讲解这道题题目,算是给大家拓展一下思维方式,其实深搜和回溯也是分不开的,毕竟最终都是用递归。

如果最终代码,发现照着回溯法模板画的话好像也能画出来,但难就难如何知道可以使用回溯,以及如果套进去

回溯 | 19 332.重新安排行程(hard)**相关推荐

  1. 代码随想录30——回溯:332重新安排行程、51N皇后、37解数独

    文章目录 1.332重新安排行程 1.1.题目 1.2.解答 1.2.1.思路 1.2.2.代码 2.51N皇后 2.1.题目 2.2.解答 3.37解数独 3.1.题目 3.2.解答 3.2.1.正 ...

  2. 代码随想录算法训练营第30天 | 51. N皇后 37.解数独 332.重新安排行程 回溯篇小结

    代码随想录系列文章目录 回溯篇 - 棋盘问题 图的dfs 文章目录 代码随想录系列文章目录 51.N皇后 37.解数独 332.重新安排行程 回溯篇小结 51.N皇后 题目链接 这道题的思路是什么样的 ...

  3. 代码随想录算法训练营第三十天| 第七章 回溯算法:332.重新安排行程,51.N皇后,37.解数独(python)

    回溯算法总结 332.重新安排行程 讲解链接 class Solution:def __init__(self):self.res = []self.dict = defaultdict(list)d ...

  4. 「leetcode」332.重新安排行程【回溯算法/深搜】详细图解!

    本文 https://github.com/youngyangyang04/leetcode-master 已经收录,里面还有leetcode刷题攻略.各个类型经典题目刷题顺序.思维导图,可以fork ...

  5. 回溯算法模板之:332. 重新安排行程

    题目链接:332.重新安排行程 分析:需要重新排列行程,并且需要按照自然排序的大小,所以第一步就先进行字典的创建,key是起始地,value是可到达所有的目的地,然后对value进行排序.使用回溯算法 ...

  6. LeetCode刷题流程:回溯算法-13.332. 重新安排行程

    332. 重新安排行程 给定一个机票的字符串二维数组 [from, to],子数组中的两个成员分别表示飞机出发和降落的机场地点,对该行程进行重新规划排序.所有这些机票都属于一个从 JFK(肯尼迪国际机 ...

  7. 代码随想录刷题|LeetCode 332.重新安排行程 51. N皇后 37. 解数独

    目录 332.重新安排行程 思路 重新安排行程 51. N皇后 思路 N皇后 37. 解数独 思路 解数独         这三道题目都是困难题目,都是根据代码随想录的思路总结书写,慢慢理解,慢慢熟练 ...

  8. 算法训练day24 | php | 332.重新安排行程 , 51. N皇后 , 37. 解数独 ,总结

    一.力扣题332. 重新安排行程 给你一份航线列表 tickets ,其中 tickets[i] = [fromi, toi] 表示飞机出发和降落的机场地点.请你对该行程进行重新规划排序. 所有这些机 ...

  9. 代码随想录算法训练营第30天| 332.重新安排行程 、51. N皇后 、 37. 解数独

    代码随想录算法训练营第30天| 332.重新安排行程 .51. N皇后 . 37. 解数独 332.重新安排行程 开始想的是将行程进行全排列之后,然后选出一个字典排序最小的.就也是使用的回溯的思路. ...

最新文章

  1. linux后台运行和关闭、查看后台任务
  2. VC++ 常用编程技巧总结
  3. 数字图像处理——第三章 空间域图像增强(灰度变换和直方图处理)
  4. abap 如何去掉字符串前导0
  5. E - 连连看 HDU - 1175(思维的深搜)
  6. 如何在Windows上使用64位Web浏览器
  7. 理解Storm Metrics
  8. 《剑指offer》第一题(重载赋值运算符)
  9. 【LeetCode 剑指offer刷题】树题4:104 Maximum Depth of Binary Tree
  10. 给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为...
  11. openwrt: Makefile 框架分析[转载]
  12. 使用python合并多个pdf文件
  13. 3.9提取电话号的区号、电话号、分机号
  14. CTF——AWD模式小总结
  15. ant的下载与安装(一)
  16. 【IOS】Object-C 中的Selector 概念
  17. 前端实现小型打包工具
  18. 定位职业赛道-抽象职业能力-修炼核心能力,打造核心竞争力,不单纯被岗位、公司、行业的选择局限
  19. 网络攻击——流量劫持
  20. dive into python 3_对象方法Dive into Python读书笔记3

热门文章

  1. html 文档设置标记,html文档设置标记
  2. 数字(1,2,3....)转为汉字(一,二,三....)
  3. cat6 万兆_CAT5E、CAT6和CAT6A在系统性能及网络应用上有什么区别?
  4. 2D与3D人脸识别详解
  5. 3D结构光人脸识别技术的优势
  6. 多维数据表达式MDX笔记
  7. Hadoop HA《hadoop-Yarn》
  8. 肠胃不好的人,怎么做,注意什么?
  9. eclipse 转idea主题风格
  10. V 2 heartbeat V2(HA)