学到了位运算的操作:
将集合映射到一个数字上,无论是比较还是入集合/出集合都很方便!
设s1,s2为集合:
将第i个项目入集合s1:
s1|=(1<<i) // 无论i之前是否在集合中
s1+=(1<<i) // 一定要保证i之前不在集合中,不然会出错
将第i个项目出集合
s1-=(1<<i) //一定要保证i之前在集合中
比较两个集合是否相同
s1==s2
解决问题的代码:
class Solution {
public:
int maxProduct(vector<string>& words) {
/*
要求不含相同字母的单词的最长长度乘积
暴力做法为枚举所有单词,判断是否成立,为o(n*n*m)
考虑如下:
因为只有26个字母,int型有32位,因此可以把包含某个字母映射为一个整数的该位置为1,反之为0
因此可以用两个整数表示一个单词,一个是表示字母出现情况的数字,另一个是表示单词长度的数字
因此可以遍历所有单词,将该单词的掩码(既上文提到的第一个数字)作为键,长度作为值,存入哈希表中,对于相通键的单词,取长度最大者
然后枚举哈希表里的两个单词即可
*/
map<int,int> mp;
for(int i=0;i<words.size();i++){
int key=0;
for(auto j:words[i]){
key|=1<<(j-'a');
}
mp[key]=max(mp[key],(int)words[i].length());
}
int ans=0;
for(auto a:mp){
for(auto b:mp){
if((a.first&b.first)==0){
ans=max(ans,a.second*b.second);
}
}
}
return ans;
}
};