其他分享
首页 > 其他分享> > 269. 火星词典(拓扑排序)

269. 火星词典(拓扑排序)

作者:互联网

269. 火星词典

现有一种使用英语字母的火星语言,这门语言的字母顺序与英语顺序不同。

给你一个字符串列表 words ,作为这门语言的词典,words 中的字符串已经 按这门新语言的字母顺序进行了排序 。

请你根据该词典还原出此语言中已知的字母顺序,并 按字母递增顺序 排列。若不存在合法字母顺序,返回 "" 。若存在多种可能的合法字母顺序,返回其中 任意一种 顺序即可。

字符串 s 字典顺序小于 字符串 t 有两种情况:

 

示例 1:

输入:words = ["wrt","wrf","er","ett","rftt"]
输出:"wertf"

示例 2:

输入:words = ["z","x"]
输出:"zx"

示例 3:

输入:words = ["z","x","z"]
输出:""
解释:不存在合法字母顺序,因此返回 "" 。

 

提示:

  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