文章目录
- 1. 题目
- 2. 解题
1. 题目
现有一种使用字母的全新语言,这门语言的字母顺序与英语顺序不同。
假设,您并不知道其中字母之间的先后顺序。
但是,会收到词典中获得一个 不为空的 单词列表。
因为是从词典中获得的,所以该单词列表内的单词已经 按这门新语言的字母顺序进行了排序。
您需要根据这个输入的列表,还原出此语言中已知的字母顺序。
示例 1:
输入:
["wrt","wrf","er","ett","rftt"
]
输出: "wertf"示例 2:
输入:
["z","x"
]
输出: "zx"示例 3:
输入:
["z","x","z"
]
输出: ""
解释: 此顺序是非法的,因此返回 ""。提示:
你可以默认输入的全部都是小写字母
若给定的顺序是不合法的,则返回空字符串即可
若存在多种可能的合法字母顺序,请返回其中任意一种顺序即可
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/alien-dictionary
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
2. 解题
参考:图Graph–拓扑排序(Topological Sorting)
- 建立第一个不相同的字符之间的有向图的边
- 记录节点的入度,把入度为0的点入队BFS
class Solution {
public:string alienOrder(vector<string>& words) {unordered_set<char> allchar;for(string& w : words){for(char ch : w)allchar.insert(ch);}//记下所有的字符unordered_map<char,int> indegree;unordered_map<char,unordered_set<char>> graph;int n1, n2, n;for(int i = 1, j; i < words.size(); ++i){ if(words[i-1] == words[i])continue;n1 = words[i-1].size();n2 = words[i].size();n = min(n1, n2);for(j = 0; j < n; ++j){if(words[i-1][j] != words[i][j]){ //不相等的第一个构成有向图的边if(!graph.count(words[i-1][j]) || !graph[words[i-1][j]].count(words[i][j])){ //防止重复添加同一条边 "za","zb","ca","cb"graph[words[i-1][j]].insert(words[i][j]);indegree[words[i][j]]++;indegree[words[i-1][j]] += 0;}break;}}if(j == n && n1 > n2)return "";//前面相等,前者长不行}queue<char> q;for(auto it = indegree.begin(); it != indegree.end(); ++it){if(it->second == 0)//入度为0的入队q.push(it->first);}string ans;while(!q.empty()){char ch = q.front();allchar.erase(ch);q.pop();ans += ch;for(auto it = graph[ch].begin(); it != graph[ch].end(); ++it){if(--indegree[*it] == 0)q.push(*it);}}if(ans.size() != indegree.size())return "";//有环while(allchar.size()){ //剩余字符随便放ans += *allchar.begin();allchar.erase(allchar.begin());}return ans;}
};
4 ms 7.2 MB
我的CSDN博客地址 https://michael.blog.csdn.net/
长按或扫码关注我的公众号(Michael阿明),一起加油、一起学习进步!