269. 火星词典(拓扑排序)
作者:互联网
269. 火星词典
现有一种使用英语字母的火星语言,这门语言的字母顺序与英语顺序不同。
给你一个字符串列表 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"
示例 2:
输入:words = ["z","x"] 输出:"zx"
示例 3:
输入:words = ["z","x","z"]
输出:""
解释:不存在合法字母顺序,因此返回 "" 。
提示:
1 <= words.length <= 100
1 <= words[i].length <= 100
words[i]
仅由小写英文字母组成
1 #include <iostream> 2 #include <vector> 3 #include <algorithm> 4 #include <string> 5 #include <unordered_map> 6 #include <unordered_set> 7 #include <queue> 8 using namespace std; 9 10 class Solution { 11 public: 12 string alienOrder(vector<string>& words) { 13 int n = words.size(); 14 if (n == 0) { 15 return ""; 16 } 17 // 1、构建图及字母的入度 18 unordered_map<char, unordered_set<char>> hashMap(26); // 邻接表存储单词中字母的先后顺序 19 vector<int> indegree(26); // 每个字母的入度 20 for (auto &word : words) { 21 for (auto &ch : word) { 22 if (hashMap.count(ch) == 0) { 23 hashMap[ch].clear(); 24 } 25 } 26 } 27 // 相邻两个字符串比较获取字母的字典序 28 for (int i = 0; i < n - 1; i++) { 29 string str1 = words[i]; 30 string str2 = words[i + 1]; 31 int minLen = min(str1.size(), str2.size()); 32 for (int j = 0; j < minLen; j++) { 33 if (str1[j] != str2[j]) { 34 /* 有向边的可以被重复添加,因为哈希表可以去重, 35 但是被指向顶点的入度不可以重复增加,为此需要做特殊判断 */ 36 // 如果字符str1[j]与str2[j]对应的边不存在,则添加边并让str2[j]的入度++ 37 if (hashMap[str1[j]].count(str2[j]) == 0) { 38 hashMap[str1[j]].insert(str2[j]); 39 indegree[str2[j] - 'a']++; 40 } 41 break; 42 } 43 // 针对特殊测试用例,["abc", "ab"],不存在这样的字典序排序结果 44 if ((j == minLen - 1) && words[i].size() > words[i + 1].size()) { 45 return ""; 46 } 47 } 48 } 49 // 输出hash表中小写字母之间的字典序 50 std::cout << "hashMap:" << endl; 51 for (auto &pair : hashMap) { 52 string tmp; 53 for (auto &ch : pair.second) { 54 tmp.push_back(ch); 55 } 56 std::cout << "key:" << pair.first << ", value:" << tmp << endl; 57 } 58 // 输出出现在hash表中的key的入度 59 std::cout << "indegree:" << endl; 60 int index = 0; 61 for (auto &pair : hashMap) { 62 std::cout << "index[" << index << "] = " << indegree[pair.first - 'a'] << "(" << pair.first << ")" << endl; 63 index++; 64 } 65 // 2、采用拓扑排序获取字母的输出顺序 66 queue<char> q; 67 for (auto &pair : hashMap) { 68 if (indegree[pair.first - 'a'] == 0) { 69 q.push(pair.first); 70 } 71 } 72 string ans; 73 int cnt = 0; // 字母访问的次数 74 while (!q.empty()) { 75 int size = q.size(); 76 for (int i = 0; i < size; i++) { 77 char temp = q.front(); 78 q.pop(); 79 cnt++; 80 ans.push_back(temp); 81 // 输出最终排序后单词中的各个字母 82 std::cout << temp << " "; 83 unordered_set<char> &nodeList = hashMap[temp]; 84 for (auto &node : nodeList) { 85 indegree[node - 'a']--; 86 if (indegree[node - 'a'] == 0) { 87 q.push(node); 88 } 89 } 90 } 91 } 92 std::cout << endl << "cnt:" << cnt << ", size:" << hashMap.size() << endl; 93 return (static_cast<int>(hashMap.size()) > cnt) ? "" : ans; 94 } 95 }; 96 int main() 97 { 98 /* 99 * 测试用例1: 100 * 输入:words = ["wrt","wrf","er","ett","rftt"] 101 * 输出:"wertf" 102 * 测试用例2: 103 * 输入:words = ["z","x"] 104 * 输出:"zx" 105 * 测试用例3: 106 * 输入:words = ["z","x","z"] 107 * 输出:"" 108 */ 109 Solution *test = new Solution(); 110 vector<string> words = {"wrt", "wrf", "er", "ett", "rftt"}; 111 string expect = "wertf"; 112 string ans = test->alienOrder(words); 113 cout << "expect ans:" << expect << ", actual ans:"<< ans << endl; 114 return 0; 115 }
标签:顺序,hashMap,int,字母,词典,words,269,拓扑,size 来源: https://www.cnblogs.com/MGFangel/p/16212033.html