第 10 章 神奇的位运算

461. 汉明距离

俩写法。
位运算。先异或,不同的就为1 。在循环与 &1,看有多少不同。每次右移直到数据用完。

class Solution {
public:
    int hammingDistance(int x, int y) 
    {
        int diff = x ^ y;
        int ans = 0;
        while(diff)
        {
            ans += diff & 1;
            diff >>= 1;
        }
        return ans;
    }
};

还有就是直接用库函数

class Solution 
{
public:
    int hammingDistance(int x, int y) 
    {
        return __builtin_popcount(x^y);
    }
};

190. 颠倒二进制位

好轮子,可以记一下。

class Solution {
public:
    uint32_t reverseBits(uint32_t n) 
    {
        int ans = 0;
        for(int i = 0;i < 32;i++)
        {
            ans <<= 1;//每次左移给低位补零
            ans += n & 1;//从最后一个数开始,如是1则ans + 1,10 -> 11
            //反之还是0,实现颠倒
            n >>= 1;//n低位舍掉
        }
        return ans;
    }
};

136. 只出现一次的数字

真的想不到,大佬真是大佬,可以记一下。位运算真是巧妙
在这里插入图片描述

class Solution {
public:
    int singleNumber(vector<int>& nums) 
    {
        int ans = 0;
        for(int num : nums)
        {
            ans ^= num;
        }
如果只出现一次 x ^ 0 = x,两次的话又变回了0 ;x ^ x = 0
        return ans;

    }
};

342. 4的幂

一个四次幂,也必定是二次幂。先判断是否是二次幂。
! ( n & (n - 1) )
在看四次幂,比如4,二进制是 100,1的位置都在偶数上,那么 n & 10101…101 ! = 0 。 偶数上的1 & 1 = 1,奇数上的0 & 0 = 0

318. 最大单词长度乘积

有点难啊。上代码分析

class Solution {
public:
    int maxProduct(vector<string>& words) 
    {
        int n = words.size();
        unordered_map<int,int> hash;//哈希表
        int ans = 0;

        for(auto word : words)
        {
            int size = word.size(),mask = 0;
            for(auto ch : word)
            {
                mask = mask | (1 << ch - 'a');
这一步把每个位置上有字符的为1,无字符的为0.如,ab = 11,ac = 101.bd = 1010
从后往前看。这里mask仅仅是与最后一位进行了或运算
            }
            
            hash[mask] = max(size,hash[mask]);
这里更新每个mask的哈希值,但是不能直接写 hash[mask] = size;
题目虽然要求两个字符串直接不可以有重复字符,但是一个字符串内会有重复的。
aa = a = 1,但是哈希值要去长度更长的2,所以要不断比较max
            for(auto [h_mask,h_len] : hash)遍历比较
            {
                if(! (mask & h_mask))判断是否有相同字符
                {
                    ans = max(ans,size * h_len);
                }
            }
        }

        return ans;

    }
};

338. 比特位计数

位运算和动规俩写法。
位运算:

class Solution {
public:
    vector<int> countBits(int n) 
    {
        vector<int> ans;
        for(int i = 0;i <= n;i++)
        {            
            int res = 0;
            int t = i;
            while(t)
            {
                res += t & 1;
                t >>= 1;
            }
ans.push_back(res);
        }
return ans;
    }
};

动规:
在这里插入图片描述

class Solution {
public:
    vector<int> countBits(int n) 
    {
       vector<int> dp(n + 1,0);

       for(int i = 1;i <= n;i++)
       {
           dp[i] = i & 1 ? dp[i - 1] + 1: dp[i >>1];
       }
       return dp;
    }
};

268. 丢失的数字

写出来了。与正确的数据异或一次,再与给出的数据异或一次返回。

0 ^ x = x;
0 ^ x ^ x =0;

693. 交替位二进制数

错位异或
在这里插入图片描述

476. 数字的补数

异或真滴强。异或,同为0不同为1,将Nums与全1数据异或,原来的0变成1,1变成0。
所以需要知道nums有几位,得到一个全1,nums.size()位的数据。
复制一个tmp = num,tmp每次右移直到tmp < 0,,res 每次左移 +1,最后res就是全1,nums.size()位的数据。与num异或即可。

260 见剑指offer 56-I

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值