题意:
定义一个单词的“兄弟单词”为:交换该单词字母顺序(注:可以交换任意次),而不添加、删除、修改原有的字母就能生成的单词。
兄弟单词要求和原来的单词不同。例如: ab 和 ba 是兄弟单词。 ab 和 ab 则不是兄弟单词。
现在给定你 n 个单词,另外再给你一个单词 str ,让你寻找 str 的兄弟单词里,按字典序排列后的第 k 个单词是什么?
注意:字典中可能有重复单词。本题含有多组输入数据。
方法一:
map
思路:map有排序功能,会将字符串按照字典序排列。遍历map,寻找单词 str 的兄弟单词,并求出兄弟单词中的第 k 个单词。
#include <bits/stdc++.h> using namespace std; int cnt[26],num[26]; int main(){ string x; int n,k; while(cin >> n){ memset(cnt,0,sizeof(cnt));//记录26个字母的个数 map<string,int> m; for(int i=0;i<n;i++){ cin >> x; m[x]++; } cin >> x >> k; for(int i=0;i<x.size();i++)//对字符串x的字母计数 cnt[x[i]-'a']++; int res=0; string ans=""; int f=0; for(map<string,int>::iterator it=m.begin();it!=m.end();it++){//遍历 string s=it->first; if(s==x)//排除本身字符串 continue; memset(num,0,sizeof(num)); if(it->first.size()!=x.size())//排除长度不一样的字符串 continue; for(int i=0;i<s.size();i++)//对每个字符串的字母计数 num[s[i]-'a']++; int flag=0; for(int i=0;i<26;i++) if(cnt[i]!=num[i]){//字符个数不满足 flag=1; break; } if(flag==0){ res+=it->second;//累加兄弟单词个数 k-=it->second; if(k<=0&&f==0){//寻找第k个兄弟单词 ans=s; f=1; } } } cout << res << endl << ans << endl; } return 0; }
时间复杂度:空间复杂度:
方法二:
快排
思路:利用快速排序实现字符串数组的排列。
然后遍历字符串数组,寻找单词 str 的兄弟单词,并求出兄弟单词中的第 k 个单词。
#include <bits/stdc++.h> using namespace std; int cnt[26],num[26]; int main(){ string x; int n,k; while(cin >> n){ memset(cnt,0,sizeof(cnt));//记录26个字母的个数 vector<string> v;//存储字符串 for(int i=0;i<n;i++){ cin >> x; v.push_back(x); } sort(v.begin(),v.end());//快排 cin >> x >> k; for(int i=0;i<x.size();i++)//对字符串x的字母计数 cnt[x[i]-'a']++; int res=0; string ans=""; for(int i=0;i<v.size();i++){//遍历 string s=v[i]; if(s==x)//排除本身字符串 continue; memset(num,0,sizeof(num)); if(s.size()!=x.size())//排除长度不一样的字符串 continue; for(int i=0;i<s.size();i++)//对每个字符串的字母计数 num[s[i]-'a']++; int flag=0; for(int i=0;i<26;i++) if(cnt[i]!=num[i]){//字符个数不满足 flag=1; break; } if(flag==0){ res++;//累加兄弟单词个数 k--; if(k==0){//寻找第k个兄弟单词 ans=s; } } } cout << res << endl << ans << endl; } return 0; }
时间复杂度:空间复杂度: