持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第27天,点击查看活动详情
说明:文章部分内容及图片出自网络,如有侵权请与我本人联系(主页有公众号:小攻城狮学前端)
作者:小只前端攻城狮、 主页:小只前端攻城狮的主页、 来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
【LeetCode 114. 外星文字典 】- JavaScript(拓扑排序+dfs)
题目描述
现有一种使用英语字母的外星文语言,这门语言的字母顺序与英语顺序不同。
给定一个字符串列表 words ,作为这门语言的词典,words 中的字符串已经 按这门新语言的字母顺序进行了排序 。
请你根据该词典还原出此语言中已知的字母顺序,并 按字母递增顺序 排列。若不存在合法字母顺序,返回 "" 。若存在多种可能的合法字母顺序,返回其中 任意一种 顺序即可。
字符串 s 字典顺序小于 字符串 t 有两种情况:
在第一个不同字母处,如果 s 中的字母在这门外星语言的字母顺序中位于 t 中字母之前,那么 s 的字典顺序小于 t 。
如果前面 min(s.length, t.length) 字母都相同,那么 s.length < t.length 时,s 的字典顺序也小于 t 。
示例 1:
输入:words = ["wrt","wrf","er","ett","rftt"]
输出:"wertf"
拓扑排序
思路分析:
拓扑排序的思路:首先我们要从words中还原出字典序,words也有可能没有按照字典序来排列,那就得要判断是不是按照字典序,而且字典序有两种而且两种都要检查,我们可以先取出来所有的第一个,压缩排序,再取出来相似的第二个,再进行压缩排序·,最后的就是结果。于是可以使用拓扑排序的思路,并且搭配上dfs来进行搜索。具体实现步骤如下:
- 我们先收集字母间大小关系
- 在进行DFS拓扑排序
- 通过path来判断是否存在环的情况,再非环情况下搜索最小的
- 最后如果有环就返回空串,否则返回path即可。
还有两个注意点:
- 注意defaultdict如果key不初始化是不存在的,所以要有
in_v[words[i][j]] = in_v[words[i][j]]
- 对于["abc","ab"]情形,需要判断前面的“ab”相等,但是后面的长度比前面小,直接返回不合法
var alienOrder = function(words) {
let c = 0;
let letters = new Set(words.join('').split(''));
let larger = new Map();
for (let l of letters) {
larger.set(l, new Set());
}
while (c < words.length-1) {
let pre = words[c];
let after = words[c+1];
for (let i=0; i<pre.length; i++) {
if (i >= after.length) return '';
if (pre[i] !== after[i]) {
if (larger.get(pre[i]).has(after[i])) return '';
larger.get(after[i]).add(pre[i]);
break;
}
}
c += 1;
}
let res = [];
let loop = false;
let visited = new Array(26).fill(false);
function dfs(n, path = new Set()) {
if (loop) return;
if (path.has(n)) {
loop = true;
return;
}
path.add(n);
let index = n.charCodeAt(0) - 'a'.charCodeAt(0);
if (!visited[index]) {
if (larger.get(n).size === 0) {
res.push(n);
visited[index] = true;
return;
}
for (let i of larger.get(n)) {
dfs(i, path);
}
visited[index] = true;
res.push(n);
}
path.delete(n);
}
for (let i of letters) {
dfs(i);
}
return loop ? '' : res.join('');
};
思考
有一说一,我是菜鸡,这题写了好多遍才A出来,我确实之前还不会拓扑排序,知道知识点,就是没敲过。我是菜鸡,o(╥﹏╥)o。。👀🤞
感谢阅读,希望能对你有所帮助,文章若有错误或者侵权,可以在评论区留言或在我的主页添加公众号联系我。
写作不易,如果觉得不错,可以「点赞」+「评论」 谢谢支持❤