ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2022-05-01 01:31:21  阅读:268  来源: 互联网

标签:顺序 hashMap int 字母 词典 words 269 拓扑 size


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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有