位运算——优选算法

一、基础位运算

按位与:&

两者为真(1)才为真(1),也可以理解为只要有假(0)就一定为假(0),如下:

按位或:|

只要有一个是真(1)则为真(1),否则为假(0)

按位异或:^

相同为假(0),相异为真(1),如下:

异或(^)运算规律:

对任意常数a,b,c有:

a^0=a,a^a=0,a^b^c=a^(b^c)

按位取反:~

真(1)变为假(0),假(0)变为真(1),如下:

位运算的优先级

关于位运算的优先级是一个让人很头疼的事情,不过也很好解决,直接简单粗暴多加括号就行,就像写宏定义一样。

二、进阶位运算

1.确定n的第x位是0还是1

把n右移x位,然后去&1,如下:

(n>>x)&1

如果结果为0则第x位为0,如果结果为1则第x位为1。

2.把n的x位改成1

把1左移x位,然后去| n,如下:

n=(1>>x)|n 或 n|=(1>>x)

3.把n的x位改成0

把1左移x位,然后按位取反后去&n,如下:

n=(~(1>>x))&n 或 n&=(~(1>>x))

4.提取二进制最右侧的1

(~n+1)&n

5.去掉二进制最右侧的1

n&(n-1)

相关题目1:231. 2 的幂 - 力扣(LeetCode)

解题代码:

cpp 复制代码
class Solution {
public:
    bool isPowerOfTwo(int n) {
        return n>0&&(n&(n-1))==0;
    }
};

相关题目2:191. 位1的个数 - 力扣(LeetCode)

解题代码:

cpp 复制代码
int hammingWeight(uint32_t n)
{
    int t=0;
    while(n)
    {
        n&=n-1;
        t++;
    }
    return t;
}

相关题目3:461. 汉明距离 - 力扣(LeetCode)

解题代码:

cpp 复制代码
class Solution {
public:
    int hammingDistance(int x, int y)
    {
        int z=x^y;
        int sum=0;
        for(int i=0;i<32;i++)
            if((z>>i)&1==1) sum++;
        return sum;
    }
};

三、位运算的应用

137. 只出现一次的数字 II - 力扣(LeetCode)

需要注意这个题用暴力方法是很好想的,但是要求使用线性的时间复杂度和常级别的空间来解决该问题。

算法思路:

  1. 开辟一个32大小的int类型空间arr
  2. 把数组中的所有数的二进制位累加到一个arr的对应位置上,比如把所有元素二进制的第1位累加到arr0位置,所有元素二进制的第2位,累加到arr1位置。
  3. 那么arri%3得到的就是只出现一次的那个元素的二进制的第i+1位。
  4. 定义一个变量m=0用来储存结果,把m的二进制位的对应位置改成arri%3。

解题代码:

cpp 复制代码
class Solution {
public:
    int singleNumber(vector<int>& nums) {
        int arr[32]={0};
        for(int i=0;i<nums.size();i++)
        {
            for(int j=0;j<32;j++)
                arr[j]+=1&(nums[i]>>j);
        }
        int m=0;
        for(int i=0;i<32;i++)
        {
            m|=(arr[i]%3)<<i;
        }
        return m;
    }
};

面试题 17.19. 消失的两个数字 - 力扣(LeetCode)

算法思路:

记:缺失的两个数字为ret1和ret2,初始化为0。

  1. 定义变量k=0,将k与1到N的数字异或(^)然后与数组中的所有元素异或(^)
  2. 通过异或(^)的规律我们可以知道异或后的结果k就是缺失的两个数字的异或结果。
  3. 找到k的二进制中的任意一个为1的第u位。
  4. 那么我们可以知道ret1和ret2的第u位是不一样的,所以我们把数组中的元素和1到N数字,分为两组。第u位为0的为一组,第u位为1的为二组,这样就把数组中缺失的数字分开了,然后让ret1异或上一组的所有元素,ret2异或上二组的所有元素,则就能得到缺失的两个数字ret1和ret2。
cpp 复制代码
class Solution {
public:
    vector<int> missingTwo(vector<int>& nums)
    {
        int k=0,n=nums.size();
        for(int i=0;i<n;i++) k^=nums[i];
        for(int j=1;j<=n+2;j++) k^=j;
        int u=0;
        while(((k>>u)&1)!=1) u++;
        int ret1=0,ret2=0;
        for(int j=0;j<n;j++)
        {
            if(((nums[j]>>u)&1)==1) ret1^=nums[j];
            else ret2^=nums[j];
        }
        for(int j=1;j<=n+2;j++)
        {
            
            if((j>>u)&1==1) ret1^=j;
            else ret2^=j;
        }
        return {ret1,ret2};
    }
};
相关推荐
念何架构之路14 分钟前
beego总体架构与工程结构
java·架构·beego
LadiesAndGentlemen16 分钟前
环球GeoAI-遥感VLM|2026-08-31|More with Less:通用 VLM 不换架构,也能在遥感基准上打平专用模型
人工智能·神经网络·目标检测·自然语言处理·aigc
杨杨杨大侠20 分钟前
一次大模型 API 请求是怎么跑起来的:从 Harness 到 GPU、并发与 KV Cache
aigc·openai·ai编程
典典分享指南22 分钟前
用飞书多维表格搭建内容管理看板
java·python·r语言·composer·symfony
AI工具测评家32 分钟前
2026知网维普AIGC检测原理拆解:快降重、笔过AI、快将AI三款降AI工具底层技术对比
人工智能·aigc·降重·ai检测·查重·降ai
智碳能碳管理平台38 分钟前
工业能耗台账标准化:能碳管理系统的数据口径怎么设计
算法·能碳管理系统·智碳能碳管理平台·企业能碳管理系统·碳排放核算软件·绿色工厂申报saas·能碳管理平台
带多刺的玫瑰1 小时前
Leecode#15刷题之三数之和
算法·leetcode·职场和发展
哭泣方源炼蛊1 小时前
并查集进阶 P1(带权并查集,并查集分类)
数据结构·c++·算法·二进制·带权并查集
东坡白菜1 小时前
windows下使用Trae启动java项目遇到的乱码问题
java
SQL-First布道者2 小时前
⚡Spring JDBC 完整体系 · 第 10 集 · 手搓 `BaseCondition`
java·spring boot·后端·spring·mybatis·spring jdbc