博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
leetcode332. 重新安排行程
阅读量:3889 次
发布时间:2019-05-23

本文共 2407 字,大约阅读时间需要 8 分钟。

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

说明:

  1. 如果存在多种有效的行程,你可以按字符自然排序返回最小的行程组合。例如,行程 ["JFK", "LGA"] 与 ["JFK", "LGB"] 相比就更小,排序更靠前
  2. 所有的机场都用三个大写字母表示(机场代码)。
  3. 假定所有机票至少存在一种合理的行程。

示例 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"]。但是它自然排序更大更靠后。

 

这个题看到了一脸懵逼,然后记录一下搜索的结果:

思路:最初的思路是top down的DFS,就是直接正向搜出正确路径,这样需要回朔状态,需要的时间复杂度很大.所以并不能过掉数据量大的数据.

看了别人的思路,基本是bottom up的DFS,就是路径是反向从最低层往上得出的.

将所有的机票用hash表保存起来,最后我们就是要找出一条路径将机票用完,并且如果有多条路径,就找字典序最小的.

我们可以构造一个hash表,key为一个地点字符串,value为一个multiset保存这个地点可以飞到的其他地方,之所以用multiset而不是set是因为从一个地方可以去别的地方几次.

并且这个数据结构是可以将数据排序的,方便我们有序的取数据.

然后我们利用DFS思想从"JFK"机场出发,按照字典序从小到达取与其连接的地点,从下一个地点再递归的搜索,直到没有和某地点相连的机票的了.我们就到达了最底层,然后往上返回路径即可.

--------------------- 
作者:小榕流光 
来源:CSDN 
原文:https://blog.csdn.net/qq508618087/article/details/51375040 
版权声明:本文为博主原创文章,转载请附上博文链接!

解析

  • 由于必须要按照字典序最小的来访问某个结点的孩子,所以在查找节点的孩子的map中使用一个优先队列存放,每次取出来的是字典序最小的;

  • 然后按照类似后序遍历的顺序遍历这个图(先访问自己孩子,然后访问自己),然后在反转过来,这样可以得到正确的答案;

  • 也可以理解为dfs的时候,是先访问自己的孩子,然后访问自己,最后将访问的顺序翻转过来即可,需要注意的时候一定要使用后序的方式,不然会在选择的时候出错(或者说不能正确访问所有的结点);

å¨è¿éæå¥å¾çæè¿°

题意及分析:将所有的机票用数组保存起来,最后我们就是要找出一条路径将机票用完,并且如果有多条路径,就找字典序最小的。最开始想到的方法是用一个hashmap<String,PriorityQueue<String>>保存每个点及其邻节点,然后使用深度遍历,第一次得到的结果便是答案(因为每次都是用的最小路径)。 另外一种方法是每次找到终点,然后删除该点继续查找下一个终点,最后得到的结果反转即可。

实际上,这道题目是计算最小的欧拉路径。通过分析可以知道:

如果一个有向图,存在欧拉路径(不是欧拉回路),那么图中的点最多只可能有两个点:degree(入)!=degree(出),并且这两个点,一个入度>出度,一个入度<出度;也有可能所有点degree(入)==degree(出),则存在欧拉回路

很明显,既然题目保证存在欧拉路径,那么JFK就是那个入度<出度的点,并且存在一个点入度>出度;或者所有点入度==出度

贪心法:从JFK开始,每次选取最小路径走,如果走不下去,只有可能遇到了终结点PP(那个入度>出度的点),这样就形成了从JFK到PP的主路径。剩下没走的边只有可能形成环,只要将环并入到主路径上就完成了最小欧拉路径的搜索!!

public class Solution {    Map
> map= new HashMap<>(); List
res = new ArrayList<>(); public List
findItinerary(String[][] tickets) { for(String[] ticket:tickets){ map.computeIfAbsent(ticket[0],k->new PriorityQueue<>()).add(ticket[1]); } dfs("JFK"); Collections.reverse(res); return res; } public void dfs(String node){ PriorityQueue
priorityQueue = map.get(node); while(priorityQueue!=null&&!priorityQueue.isEmpty()) dfs(priorityQueue.poll()); res.add(node); }}

 

你可能感兴趣的文章
iOS TextFiled 文本密码切换 光标偏移解决
查看>>
iOS 当前应用所占内存和设备可用内存
查看>>
iOS 文件属性
查看>>
UIView的layoutSubviews和drawRect方法何时调用
查看>>
iOS GCD多线程下载原理
查看>>
NSData全部API解释
查看>>
iOS 侧滑菜单封装Demo(类似QQ侧滑效果)
查看>>
Spring学习(二)
查看>>
Spring学习(三)
查看>>
Spring学习(四)
查看>>
java解惑——易错知识点归纳总结
查看>>
Memcached 集群部署
查看>>
Memcached与Spring AOP构建数分布式据库前端缓存框架
查看>>
数据挖掘常用算法整理
查看>>
JNDI学习总结(一)——JNDI数据源的配置
查看>>
JNDI学习总结(二)——Tomcat下使用C3P0配置JNDI数据源
查看>>
JNDI学习总结(三)——Tomcat下使用Druid配置JNDI数据源
查看>>
JavaWeb学习总结(四十九)——简单模拟Sping MVC
查看>>
Struts1和Struts2的区别和对比(完整版)
查看>>
在Eclipse中初用lucene
查看>>