常见位运算基础知识,技巧总结以及力扣实战

为下一章位运算算法做铺垫,知识点在C/C++文章中均出现过。

上篇文章:力扣:525.连续数组和1314.矩阵区域和(二维前缀和)

目录

1.基础位运算

2.位运算优先级

3.给一个数n,确定它的二进制表示中的第x位是0还是1

4.将一个数n的二进制表示的第x位修改为1

5.将一个数n的二进制表示的第x位修改为0

6.位图的思想

7.提取一个数(n)二进制表示最右侧的1

8.去掉一个数(n)二进制表示中最右侧的1

9.异或(^)运算的运算律

10.相关力扣算法题

[10.1 位1的个数](#10.1 位1的个数)

10.2比特位计数

10.3汉明距离

10.4只出现一次的数字

10.5只出现一次的数字


1.基础位运算

<< :按位左移运算符,将数值的二进制位整体向左移动指定的位数,右侧低位统一补 0,左侧高位超出存储位数的部分直接丢弃

>> :按位右移运算符,分为算术右移(带符号右移)和逻辑右移(无符号右移)。

算术右移(大多数语言有符号数的默认右移规则):将数值的二进制位整体向右移动指定的位数,左侧高位统一补「符号位」(正数补 0,负数补 1),右侧低位超出的部分直接丢弃

逻辑右移:将数值的二进制位整体向右移动指定的位数,无论正负,左侧高位统一补 0,右侧低位超出的部分直接丢弃

~ :按位取反

& :按位与,有0就是0

| :按位或,有1就是1

&与| 举例:

0 1 0

0 1 1


& 0 1 0

^ 0 1 1

^ :按位异或,或称为 无进位相加。相同为0,相异为1

无进位相加举例:

0 1 0

^ 0 1 1


0 0 1

其中,1与1相加为2,进位则将其丢掉,结果变为1

2.位运算优先级

需要括号,就加括号。

3.给一个数n,确定它的二进制表示中的第x位是0还是1

方法:(n>>x)& 1 分两种结果:0 -> 0或 1 -> 1

举例:

n:0 1 1 0 1 0 1 0 0 1

x位

4.将一个数n的二进制表示的第x位修改为1

公式:n |= (1 << x)

举例:

x位

0 1 1 0 1 0 1 0 1 1

| 0 0 0 0 0 1 0 0 0 0


0 1 1 0 1 1 1 0 1 1

5.将一个数n的二进制表示的第x位修改为0

公式:n &= (~(1 << x))

举例:

x位

0 1 1 0 1 0 1 0 1 1

& 1 1 1 1 1 1 0 1 1 1


0 1 1 0 1 0 0 0 1 1

6.位图的思想

int[ ]数组(哈希表思路):1 个 int 类型占 32 个二进制位,却只能标记 1 个数字的状态,空间利用率极低:

位图思路:把自身 32 个二进制位拆开,每 1 位独立对应 1 个数字的状态------ 位的值为 1,代表对应数字存在 / 已标记;位的值为 0,代表对应数字不存在 / 未标记。

7.提取一个数(n)二进制表示最右侧的1

公式:n & ((~n) + 1) 或 n & (-n)

在计算机的二进制补码体系中,负数的存储规则是:-n = ~n + 1(对原数按位取反再加 1),因此 n & (~n + 1)n & -n 是完全等价的写法,后者更简洁,是工程中更常用的形式。

(-n)的意义:将最右侧的1,左边的区域全部变为相反。

举例:

0 1 1 0 1 0 1 0 0 0

~ 1 0 0 1 0 1 0 1 1 1

+1 1 0 0 1 0 1 1 0 0 0

& 0 1 1 0 1 0 1 0 0 0


0 0 0 0 0 0 1 0 0 0

8.去掉一个数(n)二进制表示中最右侧的1

公式:n & (n - 1)

(n - 1)的含义:将最右侧的1,右边的区域(包含1)全部变成相反。

举例:

n: 0 1 1 0 1 0 1 0 0

n-1: 0 1 1 0 1 0 0 1 1

&: 0 1 1 0 1 0 0 0 0


0 1 1 0 1 0 0 0 0

9.异或(^)运算的运算律

  1. a ^ 0 = a

  2. a ^ a = 0(消消乐)

  3. a ^ b ^ c = a ^ (b ^ c)

10.相关力扣算法题

10.1 位1的个数

https://leetcode.cn/problems/number-of-1-bits/

复制代码
class Solution 
{
public:
    int hammingWeight(int n) 
    {
        int count = 0;
        unsigned int num = n;
        while(num > 0)
        {
            int lowbit = num & (-num);
            count++;
            num -= lowbit;
        }
        return count;
    }
};

10.2比特位计数

https://leetcode.cn/problems/counting-bits/description/

复制代码
class Solution {
public:
    vector<int> countBits(int n) {
        vector<int> ans(n + 1, 0);
        for(int i = 0; i <= n; i++)
        {
            int num = i;
            int count = 0;
            while(num > 0)
            {
                int lowbit = num & (-num);
                count++;
                num -= lowbit;
            }
            ans[i] = count;
        }
        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] = dp[i & (i - 1)] + 1;
        }
        return dp;
    }
};

10.3汉明距离

https://leetcode.cn/problems/hamming-distance/

复制代码
class Solution 
{
public:
    int hammingDistance(int x, int y) 
    {
        int count = 0;
        int diff = x ^ y;
        while(diff > 0)
        {
            int lowbit = diff & (-diff);
            count++;
            diff -= lowbit;
        }
        return count;
    }
};

10.4只出现一次的数字

https://leetcode.cn/problems/single-number/description/

复制代码
class Solution {
public:
    int singleNumber(vector<int>& nums) {
        int ret = 0;
        for(int num : nums)
        {
            ret ^= num;
        }
        return ret;
    }
};

10.5只出现一次的数字

https://leetcode.cn/problems/single-number-iii/

复制代码
class Solution {
public:
    vector<int> singleNumber(vector<int>& nums) {
        int diff = 0;
        for(int num : nums)
        {
            diff ^= num;
        }

        int lowbit = diff & (-diff);
        int a = 0, b = 0;
        for(int num : nums)
        {
            if(num & lowbit) a ^= num;
            else b ^= num;
        }
        return {a,b};
    }
};

本章完。

相关推荐
Liudef0619 分钟前
后量子密码学(PQC)深度解析:算法原理、标准进展与软件开发行业的影响
算法·密码学·量子计算
OYpBNTQXi2 小时前
SEAL全同态加密CKKS方案入门详解
算法·机器学习·同态加密
筱璦2 小时前
期货软件开发 - C# 调用 HQChart 指标计算 C++ 动态库
c++·microsoft·c#
yuannl102 小时前
数据结构----队列的实现
数据结构
蚂蚁数据AntData2 小时前
破解AI“机器味“困境:HeartBench评测实践详解
大数据·人工智能·算法·机器学习·语言模型·开源
ZC跨境爬虫2 小时前
Python异步IO详解:原理、应用场景与实战指南(高并发爬虫首选)
爬虫·python·算法·自动化
不想写代码的星星2 小时前
C++ 内存管理:分区、自定义分配器、常见问题与检测工具
c++
Mr_Xuhhh2 小时前
从ArrayList到LinkedList:理解链表,掌握Java集合的另一种选择
java·数据结构·链表
倦王2 小时前
力扣日刷47-补
python·算法·leetcode
-许平安-3 小时前
MCP项目笔记九(插件 bacio-quote)
c++·笔记·ai·plugin·mcp