位运算-leetcode

1 左右移动(老是写反)
a>>1; 向右移动1位 a<<1; 向左移动1位
注意:有符号数在右移运算中:移出去的位丢弃,空缺位(vacant bit)用“符号位”来填充,正数用0,负数用1。
2 判断奇数偶数:
if ((a & 0x0001) == 0)代替if (a % 2 == 0)
3 取最低位:(a & 0x0001)
4 乘2除2:a << 1; a >> 1;
5 去掉最右边的1:a&(a-1)

201. Bitwise AND of Numbers Range

0 <= m <= n <= 2147483647,求取m到n相与运算的结果。
思路分析:

231. Power of Two

判断一个数是不是2的幂次方
思路分析:
2的倍数的形式为100..所以去掉最右边的1后结果如果为0,则是2的倍数,否则不是2的倍数。

class Solution {
    public:
        bool isPowerOfTwo(int n) {
        //简化为一句话return n > 0 && !(n&(n-1));
            if (n <= 0) return false;
            return !(n&(n-1));
            }
    };

342. Power of Four

判断一个数是不是4的幂次方
思路分析:先判断是不是2的幂次方,再判断1是不是在在奇数位上:

class Solution {
public:
    bool isPowerOfFour(int num) {
        if (num <= 0) return false;
        if (num&(num-1)) return false;
        int count = 0;
        while(!(num&0x0001)){
            num = num >> 1;
            ++count;
        }
        return !(count&0x0001);
    }
};

改进版:

public class Solution {
    public boolean isPowerOfFour(int num) {
        return (num > 0) && ((num & (num - 1)) == 0) && ((num & 0x55555555) == num);
        //return num > 0 && (num & (num - 1)) == 0 && (num - 1) % 3 == 0;
    }
}

318. Maximum Product of Word Lengths

这里写图片描述
思路:重点是求两个字符串是否有相同的字符,所以这里的做法是把字符串转化为整数,然后作与运算。
实际过程中,代码运行忘了加括号出了bug:
if ((words2num[i] & words2num[j]) == 0)
与的优先级低于比较运算的优先级。

class Solution {
public:
    int maxProduct(vector<string>& words) {
        vector<int> words2num(words.size());     
        int maxVal = 0;
        for (int i = 0; i < words.size(); ++i){
            for (int j = 0; j < words[i].size(); ++j){
                words2num[i] |= 1 << (int)(words[i][j] - 'a');
            }
        }
        for (int i = 0; i < words2num.size(); ++i){
            for (int j = i + 1; j < words2num.size(); ++j){
                if ((words2num[i] & words2num[j]) == 0)
                    maxVal = max((int)(words[i].size() * words[j].size()), maxVal);
            }
        }
        return maxVal;
    }
};

改进版1:

int maxProduct(vector<string>& words) {
    vector<int> mask(words.size());
    int result = 0;
    for (int i=0; i<words.size(); ++i) {
        for (char c : words[i])
            mask[i] |= 1 << (c - 'a');
        for (int j=0; j<i; ++j)
            if (!(mask[i] & mask[j]))
                result = max(result, int(words[i].size() * words[j].size()));
    }
    return result;
}

改进版2:

int maxProduct(vector<string>& words) {
    unordered_map<int,int> maxlen;
    for (string word : words) {
        int mask = 0;
        for (char c : word)
            mask |= 1 << (c - 'a');
        maxlen[mask] = max(maxlen[mask], (int) word.size());
    }
    int result = 0;
    for (auto a : maxlen)
        for (auto b : maxlen)
            if (!(a.first & b.first))
                result = max(result, a.second * b.second);
    return result;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值