题意

给N个单词表示N个点,和N-1个单词对,表示可以走的路径,求字典序最小的总路径。

首先说下这么暴力DFS能过。暴力的我都不敢写= =

class Solution {
public:
vector<string> findItinerary(vector<vector<string> >& tickets) {
map<string, vector<string> > mp; for (int i = 0; i < tickets.size(); i++) {
string from = tickets[i][0];
string to = tickets[i][1];
if (mp.find(from) == mp.end()) {
vector<string> v;
v.push_back(to);
mp[from] = v;
} else {
mp[from].push_back(to);
}
}
for (map<string, vector<string> >::iterator iter = mp.begin(); iter != mp.end(); iter++) {
sort(iter->second.begin(), iter->second.end());
}
vector<string> res;
string cur = "JFK";
res.push_back(cur);
dfs(cur, mp, res, tickets.size());
return res;
} bool dfs(string cur, map<string, vector<string> > &mp, vector<string> &res, int n) {
if (res.size() == n + 1) return true;
if (mp.find(cur) == mp.end()) return false;
if (mp[cur].size() == 0) return false;
for (int i = 0; i < mp[cur].size(); i++) {
string nxt = mp[cur][i];
res.push_back(nxt);
mp[cur].erase(mp[cur].begin() + i);
if (dfs(nxt, mp, res, n)) return true;
mp[cur].insert(mp[cur].begin() + i, nxt);
res.pop_back();
}
return false;
}
};

然后说正解。

如果把每一个字符串当做一个点,每一个字符串对就是一条有向边。那么这么题目就是要求输出最小字典序的欧拉路径。

以下参考 https://www.cnblogs.com/TEoS/p/11376707.html

什么是欧拉路径?欧拉路径就是一条能够不重不漏地经过图上的每一条边的路径,即小学奥数中的一笔画问题。而若这条路径的起点和终点相同,则将这条路径称为欧拉回路。

如何判断一个图是否有欧拉路径呢?显然,与一笔画问题相同,一个图有欧拉路径需要以下几个条件:

  • 首先,这是一个连通图
  • 若是无向图,则这个图的度数为奇数的点的个数必须是0或2;若是有向图,则要么所有点的入度和出度相等,要么有且只有两个点的入度分别比出度大1和少1

上面这两个条件很好证明。查找欧拉路径前,必须先保证该图满足以上两个条件,否则直接判误即可。

查找欧拉路径的算法有Fluery算法和Hierholzer算法。下面介绍一下Hierholzer算法。

算法流程:

  1. 对于无向图,判断度数为奇数的点的个数,若为0,则设任意一点为起点,若为2,则从这2个点中任取一个作为起点;对于有向图,判断入度和出度不同的点的个数,若为0,则设任意一点为起点,若为2,则设入度比出度小1的点为起点,另一点为终点。具体起点的选择要视题目要求而定。
  2. 从起点开始进行递归:对于当前节点x,扫描与x相连的所有边,当扫描到一条(x,y)时,删除该边,并递归y。扫描完所有边后,将x加入答案队列。
  3. 倒序输出答案队列。(因为这里是倒序输出,我们可以用栈来存储答案,当然用双端队列也可以)

我画图理解一下这个算法,一个欧拉路径其实都是这个样子的

就是从起点到终点的路径上画几个圈。

举两个具体的例子

path = []

A --> B --> C 因为C没有再相连的边 所以把C加入路径 path=[C]

    --> D --> B 因为B没有再相连的边 所以把B加入路径 path=[C, B]

      D  path=[C, B, D]

   B path=[C, B, D, B]

A path=[C, B, D, B, A]

path = []

A --> B --> C --> B --> D 因为D没有再相连的边 所以把D加入路径 path=[D]

          B path=[D, B]

      C path=[D, B, C]

   B path=[D, B, C, B]

A path=[D, B, C, B, A]

所以无论先遍历的那一条边都能得出正确的欧拉路径,既然题目要求字典序,那么每次选择最小字符串先处理即可。

代码

class Solution {
public:
vector<string> findItinerary(vector<vector<string> >& tickets) {
map<string, priority_queue<string,vector<string>,greater<string> > > mp; for (int i = 0; i < tickets.size(); i++) {
string from = tickets[i][0];
string to = tickets[i][1];
if (mp.find(from) == mp.end()) {
priority_queue<string,vector<string>,greater<string> > q;
q.push(to);
mp[from] = q;
} else {
mp[from].push(to);
}
}
vector<string> res;
string cur = "JFK";
dfs(cur, mp, res);
reverse(res.begin(), res.end());
return res;
} void dfs(string cur, map<string, priority_queue<string,vector<string>,greater<string> > > &mp, vector<string> &res) {
while(mp[cur].size()) {
string nxt = mp[cur].top();
mp[cur].pop();
dfs(nxt, mp, res);
}
res.push_back(cur);
}
};

LeetCode 332. Reconstruct Itinerary 最小欧拉路径的更多相关文章

  1. [leetcode]332. Reconstruct Itinerary

    Given a list of airline tickets represented by pairs of departure and arrival airports [from, to], r ...

  2. 【LeetCode】332. Reconstruct Itinerary 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 后序遍历 相似题目 参考资料 日期 题目地址:htt ...

  3. 【LeetCode】Reconstruct Itinerary(332)

    1. Description Given a list of airline tickets represented by pairs of departure and arrival airport ...

  4. 【LeetCode】332. Reconstruct Itinerary

    题目: Given a list of airline tickets represented by pairs of departure and arrival airports [from, to ...

  5. 332. Reconstruct Itinerary (leetcode)

    1. build the graph and then dfs -- graph <String, List<String>>,  (the value is sorted a ...

  6. 332 Reconstruct Itinerary 重建行程单

    Given a list of airline tickets represented by pairs of departure and arrival airports [from, to], r ...

  7. 332. Reconstruct Itinerary

    class Solution { public: vector<string> path; unordered_map<string, multiset<string>& ...

  8. [LeetCode] Reconstruct Itinerary 重建行程单

    Given a list of airline tickets represented by pairs of departure and arrival airports [from, to], r ...

  9. LeetCode Reconstruct Itinerary

    原题链接在这里:https://leetcode.com/problems/reconstruct-itinerary/ 题目: Given a list of airline tickets rep ...

  10. [Swift]LeetCode332. 重新安排行程 | Reconstruct Itinerary

    Given a list of airline tickets represented by pairs of departure and arrival airports [from, to], r ...

随机推荐

  1. Ubuntu本地安装Docker

    Ubuntu本地安装Docker 目录 Ubuntu本地安装Docker 查看Ubuntu系统版本代号 安装 修改镜像源 官方文档:Install Docker Engine on Ubuntu | ...

  2. top的wa,mpstat的%iowait以及pidstat的%wait

    top的wa,mpstat的%iowait以及pidstat的%wait pidstat 中, %wait 表示进程等待 CPU 的时间百分比.等待 CPU 的进程已经在 CPU 的就绪队列中,处于运 ...

  3. [VS Code扩展]写一个代码片段管理插件(一):介绍与界面搭建

    @ 目录 VS Code扩展机制 项目搭建 创建UI元素 活动栏按钮 主边栏视图 主边栏工具栏按钮 侧边栏右键菜单 编辑器右键菜单 项目地址 [VS Code扩展]写一个代码片段管理插件(一):介绍与 ...

  4. Rust项目的代码组织

    学习一种编程语言时,常常优先关注在语言的语法和标准库上,希望能够尽快用上新语言来开发,我自己学习新的开发语言时也是这样. 不过,想用一种新的语言去开发实际的项目,或者自己做点小工具的话,除了语言本身之 ...

  5. python库 —— gym retro 的 ROMs文件下载地址

    如题: python库 -- gym retro 的 ROMs文件下载地址: https://archive.org/details/No-Intro-Collection_2016-01-03_Fi ...

  6. 在Vue3中如何为路由Query参数标注类型

    前言 最近发布了一款支持IOC容器的Vue3框架:Zova.与以往的OOP或者Class方案不同,Zova在界面交互层面仍然采用Setup语法,仅仅在业务层面引入IOC容器.IOC容器犹如一把钥匙,为 ...

  7. 证明: 设n阶方阵A相似于对角阵Λ, λ是A的k重特征值, 则r(λE-A)=n-k.

    命题: 设n阶方阵A相似于对角阵Λ, λ是A的k重特征值, 则r(λE-A)=n-k.证明: 由定理3.9: A~Λ <=> A有n个线性无关的特征向量, 知k重特征值λ存在k个线性无关的 ...

  8. 社区6月月报 | Apache DolphinScheduler重要修复和优化记录

    各位热爱Apache DolphinScheduler的小伙伴们,社区6月月报更新啦!这里将记录Apache DolphinScheduler社区每月的重要更新,欢迎关注. 月度Merge Stars ...

  9. ComfyUI插件:ComfyUI_Noise节点

    前言: 学习ComfyUI是一场持久战,ComfyUI_Noise是对ComfyUI中的噪声进行控制的一个插件库,该库可以完成图像噪声的反推,并通过采样再以几乎无损的方式返回原图,通过该库的使用可以更 ...

  10. java增量发布工具

    有些公司由于没有使用maven作为构建工具,全量发布时没问题,而修改bug增量发布往往是将改动的代码手动编译后,从classes目录下拷贝到jar中然后再放到tomcat目录下发布,这种方法准确度不高 ...