【C++位运算】318. 最大单词长度乘积/C++/leedcode/源码

C++位运算 题目在文章末尾

1. >>= 右移并赋值

示例:

int n = 0;
n = 8;  // 00000000 00000000 00000000 00000100 十进制8的二进制表示
n >>= 3;// 00000000 00000000 00000000 00000001 将n右移三位并赋值给n
//等价于 n = n >> 3;

2. <<= 左移并赋值

示例:

int n = 0;
n = 1;  // 00000000 00000000 00000000 00000001 十进制1的二进制表示
n <<= 3;// 00000000 00000000 00000000 00000100 将n右移三位并赋值给n
//等价于 n = n << 3;

3. &= 按位与后赋值

与操作真值表:

&01
000
101

按位与常用技巧:
1.提取一个数中的某一位,如下:

int a, b, n;
b = a & (1 << n); //提取a中的右数第n - 1位

示例:

int n = 0;
n = 7; // 00000000 00000000 00000000 00000111 十进制7的二进制表示
n &= 5;// 00000000 00000000 00000000 00000101 十进制5的二进制表示
//按位与后结果为00000000 00000000 00000000 00000101 十进制5的二进制表示
//等价于 n = n & 5;

4. |= 按位与后赋值

与操作真值表:

^01
001
111

与操作常用技巧:
1.用整型的每一位当作hash表进行记录(本题中使用),示例见文末源码。

示例:

int n = 0;
n = 6; // 00000000 00000000 00000000 00000110 十进制6的二进制表示
n &= 3;// 00000000 00000000 00000000 00000011 十进制3的二进制表示
//按位与后为00000000 00000000 00000000 00000111 十进制7的二进制表示
//等价于 n = n | 3;

5. ^= 按位异或后赋值

与操作真值表:

^01
001
110

示例:

int n = 0;
n = 6; // 00000000 00000000 00000000 00000110 十进制6的二进制表示
n &= 3;// 00000000 00000000 00000000 00000011 十进制3的二进制表示
//按位与后为00000000 00000000 00000000 00000101 十进制5的二进制表示
//等价于 n = n ^ 3;

实战:Leedcode 318. 最大单词长度乘积

简易题解
vector数组中每一个string字符串对应一个int记录其字符信息,int从0~25位分别对应a、b、c、d、······x、y、z,每一位是否为1代表该位对应的字母是否存在(0不存在,1存在),例如101代表含有a, c,不含有b。再将int一个个分别比较,通过与运算判断其是否有重复字符,在无重复中,找出最大值。

源码

int maxProduct(vector<string>& words) {
    int n = words.size();
    vector<int> v(n); //记录字符串中的字符信息
    int res = 0;
    for (int i = 0; i < n; i++) {  //用int的每一位计数,当作hash标志
        string word = words[i];
        int wordLength = word.size();
        for (int j = 0; j < wordLength; j++) {
            /*int p = 1 << (word[j] - 'a'); //pow(2, (word[j] - 'a')) 用移位更快
              if(!(v[i] & p)) v[i] += ;*/
            v[i] |= (1 << (word[j] - 'a')); //按位或即可 按位异或、与或、或、与,想好关系再用
        }
    }
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
            if ((v[i] & v[j]) == 0 && res < words[i].length() * words[j].length())
                res = words[i].length() * words[j].length();
        }
    }
    return res;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值