[Locked] Alien Dictionary
Alien Dictionary
There is a new alien language which uses the latin alphabet. However, the order among letters are unknown to you. You receive a list of words from the dictionary, where words are sorted lexicographically by the rules of this new language. Derive the order of letters in this language.
For example, Given the following words in dictionary,
[
"wrt",
"wrf",
"er",
"ett",
"rftt"
]
The correct order is: "wertf"
.
Note: You may assume all letters are in lowercase. If the order is invalid, return an empty string. There may be multiple valid order of letters, return any one of them is fine.
分析:
前后关系可看做是一种偏序关系,对于每个序列,可以看成是有向图,所有序列合在一起就成了一个大的有向图,本题可转换成有向图的拓扑排序,用BFS可解决。主要过程包含:1、根据string数组的信息映射成图;2、在图上计算出所有节点的入度;3、进行BFS,得到拓扑排序结果。故我用三个子函数来分别处理这三个过程。
代码:
//将string数组映射到图上,最坏时间复杂度就是每个字母遍历一遍,这也是必要,故也是最低时间复杂度
unordered_multimap<char, char> mapping(vector<string> &vs) {
//先处理第一列,用validcomp来记录哪些相邻行的值相等,用于后面的列的处理,不相等的就可以得偏序条件,用边来表示,存入edges中;然后处理第二列,以此类推。
unordered_multimap<char, char> edges;
unordered_set<int> validcomp, temp;
for(int i = ; i < vs.size(); i++)
validcomp.insert(i);
int j = ;
while(!validcomp.empty()) {
for(int pos : validcomp) {
if(vs[pos][j] != vs[pos - ][j])
edges.insert(make_pair(vs[pos - ][j], vs[pos][j]));
else
temp.insert(pos);
}
unordered_set<int> ().swap(validcomp);
validcomp.swap(temp);
j++;
}
return edges;
} //返回所有节点的入度,存入degree里
unordered_map<char, int> getDegree(unordered_multimap<char, char> &edges) {
unordered_map<char, int> degree;
for(char c = 'a'; c <= 'z'; c++) {
auto range = edges.equal_range(c);
auto pos = range.first;
while(pos != range.second) {
//指出节点未出现过,则设0,否则跳过;指入节点未出现过,则设1,否则++。
if(degree.find(pos->first) == degree.end())
degree[pos->first] = ;
if(degree.find(pos->second) != degree.end())
degree[pos->second]++;
else
degree[pos->second] = ;
pos++;
}
}
return degree;
} //进行BFS,用最朴素的方法,复杂度为O(N^2),用这个方法找到符合题目要求的顺序,如果能遍历完全所有节点,则return这个顺序;否则,return ""
bool bfs(string &str, unordered_map<char, int> degree, unordered_multimap<char, char> &edges) {
bool visited[];
memset(visited, , );
for(int i = ; i < degree.size(); i++) {
for(auto m : degree)
//入度为0则排入,然后更新入度hash表
if(!visited[int(m.first - 'a')] && m.second == ) {
visited[int(m.first - 'a')] = true;
str += m.first;
auto range = edges.equal_range(m.first);
auto pos = range.first;
while(pos != range.second) {
degree[pos->second]--;
pos++;
}
break;
}
}
//有环,则return ""
for(auto m : degree)
if(m.second != )
return false;
return true;
}
//主函数
string validOrder(vector<string> vs) {
//string数组映射到图edges上
unordered_multimap<char, char> edges = mapping(vs);
//返回所有节点的入度,存入degree;如果无效,则return "";
unordered_map<char, int> degree = getDegree(edges);
//进行BFS,找到合适的顺序,优先排入入度为0的点
string str = "";
bool valid = bfs(str, degree, edges);
return valid ? str : "";
}
其中,BFS过程,即函数bfs复杂度为O(N^2),N为节点个数,有改进的空间;可以优化为O(E),E为边的个数
//优化BFS
bool bfs(string &str, unordered_map<char, int> degree, unordered_multimap<char, char> &edges) {
queue<char> myq, temp;
for(auto m : degree)
if(m.second == )
myq.push(m.first);
while(!myq.empty()) {
while(!myq.empty()) {
char c = myq.front();
str += c;
myq.pop();
auto range = edges.equal_range(c);
auto pos = range.first;
while(pos != range.second) {
degree[pos->second]--;
if(degree[pos->second] == )
temp.push(pos->second);
pos++;
}
}
queue<char> ().swap(myq);
myq.swap(temp);
}
//有环,则return ""
for(auto m : degree)
if(m.second != )
return false;
return true;
}
[Locked] Alien Dictionary的更多相关文章
- 【Leetcode_easy】953. Verifying an Alien Dictionary
problem 953. Verifying an Alien Dictionary solution: class Solution { public: bool isAlienSorted(vec ...
- Verifying an Alien Dictionary
2019-11-24 22:11:30 953. Verifying an Alien Dictionary 问题描述: 问题求解: 这种问题有一种解法是建立新的排序和abc排序的映射,将这里的str ...
- [LeetCode] Alien Dictionary 另类字典
There is a new alien language which uses the latin alphabet. However, the order among letters are un ...
- 269. Alien Dictionary 另类字典 *HARD*
There is a new alien language which uses the latin alphabet. However, the order among letters are un ...
- Alien Dictionary
There is a new alien language which uses the latin alphabet. However, the order among letters are un ...
- LeetCode Alien Dictionary
原题链接在这里:https://leetcode.com/problems/alien-dictionary/ 题目: There is a new alien language which uses ...
- Leetcode: Alien Dictionary && Summary: Topological Sort
There is a new alien language which uses the latin alphabet. However, the order among letters are un ...
- 269. Alien Dictionary
题目: There is a new alien language which uses the latin alphabet. However, the order among letters ar ...
- [Swift]LeetCode269. 外星人词典 $ Alien Dictionary
There is a new alien language which uses the latin alphabet. However, the order among letters are un ...
随机推荐
- Linux下的CPU使用率与服务器负载的关系与区别
原文链接:http://blogread.cn/it/article/7444 当我们使用top命令查看系统的资源使用情况时会看到load average,如下图所示,它表示系统在1,5,15分钟的平 ...
- Android开发手记(31) 使用MediaRecorder录音
使用Android手机的时候,有时我们会用到录音功能,本文简单的介绍了如何使用MediaRecorder通过手机自带麦克风进行录音. 首先,既然是录音,我们需要录音和写外存的权限: <uses- ...
- android menu菜单自动生成
Android提供了一些简单的方法来为应用添加Menu菜单. 提供了三种类型应用菜单: 一.Options Menu:通过Menu按钮调用菜单 1.在/res/目录下新建menu文件夹,用于存储Men ...
- ASP 调用dll(VB)及封装dll实例
ASP调用dll及封装dll实例,封装为dll可以提供运行效率,加密代码. 打开VB6,新建ActiveX DLL 2.在工程引用中加入Microsoft Active Server Pages Ob ...
- 关于c:\fakepath\的解决办法
(2014.11.25 最后更新) 一.碎碎念:关于访问本地图片的路径的问题,比较典型的例子就是上传头像.在以往的解决办法中,我们大多是先将图片上传到服务器然后从服务器返回图片,显示在页面上以达到预览 ...
- javascript——面向对象程序设计(3)
<script type="text/javascript"> //1.结合使用构造函数模式和原型模式 //2.动态原型模式 //3.寄生构造函数模式 //4.稳妥构造 ...
- SQL 左外连接查询 将右表中的多行变为左表的一列或多列
示例: --行列互转 /**************************************************************************************** ...
- TortoiseSVN显示图标不正常
Windows Explorer Shell支持的Overlay Icon最多15个,除去系统使用,只有11个.如果其他程序占用了,那么乌龟SVN就无法显示了.注册表定位到:HKEY_LOCAL_MA ...
- 【技术宅11】php入门运算
//1.空bool $a=''; $b=NULL; $c=false; $d=0; $e='0'; $f=array(); $g=array(array()); $h='NULL'; var_dump ...
- Python Tutorial 学习(一)--Whetting Your Appetite
Whetting Your Appetite [吊你的胃口]... 这里就直接原文奉上了... If you do much work on computers, eventually you fin ...