描述
题目来自leetcode
二题解:
可以采用回溯代换数字,然后进行数字排序,也可以直接采用拓扑排序,回溯代换数字的代码结构要比拓扑排序的复杂且复杂度要高,不过针对数据量少的数据集还是可以用的。
/**
* @param {string[]} words
* @return {string}
*/
var getCode = function(a) {
return a.charCodeAt(0) - 97;
}
var getChar = function(code){
return String.fromCharCode(code + 97);
};
var alienOrder = function(words) {
var ans = "";
var edge = [];
var v = [];
var visited = [];
var used = [];
for(let i = 0; i < 26; i++) {
edge[i] = [];
v[i] = 0; visited[i] = 0;used[i] = 0;
for(let j = 0; j < 26; j++) {
edge[i][j] = -1;
}
}
if(words.length <= 1) {
return words[0];
}
for(let i = 1; i < words.length; i++) {
let pos = 0;
let find = -1;
while(pos < words[i-1].length && pos < words[i].length) {
if(words[i-1][pos] == words[i][pos]) {
pos++;
} else {
find = pos;
break;
}
}
if(find < 0) {
if(words[i-1].length > words[i].length) { return ""; }
} else {
let f_code = getCode(words[i-1][pos]);
let s_code = getCode(words[i][pos]);
if(edge[s_code][f_code] != -1) { return ""; }
if(edge[f_code][s_code] == 1) {continue;}
edge[f_code][s_code] = 1; v[s_code]++;used[f_code] = 1; used[s_code] = 1;
}
}
//拓扑排序
const T_SORT = () => {
let queue = [];
for(let i = 0; i < v.length; i++) {
if(v[i] == 0 && used[i]) { queue.unshift(i);}
}
let count = 0;
for(let i = 0; i < used.length; i++) {
if(used[i]) {count++;}
}
if(count == 0) { return true; }
if(queue.length == 0) { return false; }
while(queue.length > 0) {
let cur_node = queue.pop();
count--;
ans = ans + getChar(cur_node); visited[cur_node] = 1;
for(let i = 0; i < 26; i++) {
if(edge[cur_node][i] == 1) {
if(visited[i]) { return false;}
v[i]--;
if(v[i] == 0) { queue.unshift(i);}
}
}
}
if(count > 0) { return false; }
return true;
}
if(!T_SORT()) { return ""; }
for(let i = 0; i < words.length; i++) {
for(let j = 0; j < words[i].length; j++) {
if(!used[getCode(words[i][j])]) {
ans = ans + words[i][j];
used[getCode(words[i][j])] = 1;
}
}
}
return ans;
};