力扣 318和位运算集合

学到了位运算的操作:
将集合映射到一个数字上,无论是比较还是入集合/出集合都很方便!
设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;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值