题解 | #查找兄弟单词#
查找兄弟单词
https://www.nowcoder.com/practice/03ba8aeeef73400ca7a37a5f3370fe68
- 用multiset<string>存储找到的兄弟单词,即可自动排序,之所以不用set是因为题目说明“字典中可能有重复元素”,因此兄弟单词中也可能有重复元素
- 如何判断字典中的元素是否为 x 的兄弟单词?题目说了可以移动无限次,就不能用交换字母的方法来比较,因为很难穷举,应该直接比较两个单词中对应字母的出现次数即可,也就是说,设单词w1中字母a~z出现的次数分别为w1[0]~w[25],单词w2为w2[0]~w2[25],直接比较数组w1与w2是否相同即可,还要加上 w1 != w2(兄弟单词不能相同)
- 时间复杂度O(NlogN),空间O(N)
#include <iostream> #include <vector> #include <unordered_set> #include <set> #include <string> using namespace std; struct Word { string s; vector<int> w; // 哈希数组,w[0]~w[25]对应s中a~z的数量 }; bool isEqual(vector<int>& w1, vector<int>& w2) // 比较两个哈希数组是否相同 { for (int i = 0; i < 26; ++i) { if (w1[i] != w2[i]) return false; } return true; } int main() { // 读取字典 int n, k; cin >> n; string s; vector<Word> v(n); for (int i = 0; i < n; ++i) { cin >> v[i].s; vector<int> temp(26, 0); for (auto c : v[i].s) temp[c - 'a']++; v[i].w.assign(temp.begin(), temp.end()); } // 读取 x 和 k struct Word x; cin >> x.s >> k; vector<int> temp(26, 0); for (auto c : x.s) temp[c - 'a']++; x.w.assign(temp.begin(), temp.end()); // 找兄弟单词,插入multiset(字典有重复元素) multiset<string> bro; for (auto word : v) { if (word.s != x.s && isEqual(word.w, x.w)) bro.insert(word.s); } cout << (int)bro.size() << endl; // 输出第 k 个兄弟单词 int cnt = 1; for (auto s : bro) { if (cnt == k) { cout << s; break; } cnt++; } cout << endl; } // 64 位输出请用 printf("%lld")