芝士算法(位运算)

关于位运算的使用 可以从 C语言就开始使用

这里简单介绍常见的位运算

目录

[对数字第 x 位的常用操作](#对数字第 x 位的常用操作)

异或三大核心性质

判断字符是否唯一

丢失的数字

两整数求和

丢失的两个数字

只出现一次的数字||


  • & 按位与:同 1 得 1;判奇偶、清零位
  • | 按位或:有 1 得 1;置 1 特定位
  • ^ 异或:不同得 1;交换数字、翻转位
  • ~ 取反 :0、1 互换;~x = -x-1
  • << 左移:左移 n 位,低位补 0 ≈ ×2ⁿ
  • >> 右移
    • 算术右移 (有符号):补符号位 ≈ ÷2ⁿ
    • 逻辑右移 (无符号):高位补 0

对数字第 x 位的常用操作

  • 查询第 x 位是 0 / 1(n >> x) & 1
  • 把第 x 位设置为 1n |= (1 << x)
  • 把第 x 位设置为 0n &= ~(1 << x)

异或三大核心性质

  1. a ^ 0 = a
  2. a ^ a = 0(抵消)
  3. a ^ b ^ c = a ^ (b ^ c)(交换律、结合律)

提取二进制最右侧的 1n & -n

清除二进制最右侧的 1n & (n - 1)

判断字符是否唯一

判断字符是否唯一

java 复制代码
public boolean isUnique(String astr) {
        if(astr.length() > 26)
        return false;

        //
        int bitMap = 0;
        for(int i = 0; i <astr.length();i++){
            int x = astr.charAt(i) - 'a';
            if(((bitMap >> x) & 1) == 1)
            return false;
            //加入到位图中
            bitMap |= (1 << x);
        }
        return true;
    }

丢失的数字

丢失的数字

java 复制代码
 public int missingNumber(int[] nums) {
        int ret = 0;
        for(int num : nums)
        ret^= num;
        for(int i = 0; i <= nums.length; i++ )
        ret ^= i;
        
        return ret;        
    }

两整数求和

两整数求和

java 复制代码
 public int getSum(int a, int b) {
        while(b != 0){
            int x = a ^ b;
            int carry = (a & b) << 1;
            a = x;
            b = carry;
        }
        return a;
    }

丢失的两个数字

丢失的两个数字

java 复制代码
   public int[] missingTwo(int[] nums) {

        //1.丢失的数字
        int tmp = 0;
       
        for(int x : nums){
          tmp ^= x;//将全部数据异或
        }
        for(int i = 0; i<= nums.length + 2; i++){
            tmp^= i;
        }
         

        //2. 找出 a,b 不同的比特位
         int diiff = 0;
        while(true) {
            if(((tmp >> diiff) & 1) == 1 )
            break;
            else
            diiff++;
        }

        
        //3.只消失的一个数字|||
       int[] ret = new int[2];
        for(int x : nums){
        if(((x >> diiff) & 1 ) == 1)
        ret[0] ^= x;
        else
        ret[1] ^= x;
       }
       
       for(int i = 0; i <= nums.length + 2;i++){
        if(((i >> diiff) & 1) == 1 )
        ret[0] ^= i;
        else
        ret[1] ^= i;
       }
       return ret;
    }

只出现一次的数字||

只出现一次的数字||

java 复制代码
 public int singleNumber(int[] nums) {
        int ret = 0;
        for(int i = 0; i < 32; i++){
            int sum = 0;
            for( int x : nums)
            if((( x >> i )&1) == 1)
            sum++;
            sum %= 3;
            if(sum == 1)
            ret |= (1 << i);
        }
        return ret;
    }
相关推荐
她说可以呀1 小时前
Spring-ai 2.0 MCP
java·人工智能·spring
Livia要学习1 小时前
Python三种常见高阶函数--map、filter、sorted
开发语言·python
wabs6661 小时前
关于图论【Kruskal算法|卡码网53.寻宝的思考】
数据结构·算法·图论·卡码网
hans汉斯1 小时前
人工智能与机器人研究|面向无标签数据的三维场景语义理解方法研究
人工智能·神经网络·算法·信息可视化·cnn·机器人
奇树谦1 小时前
ZeroMQ 详解:轻量级高性能消息通信框架及 C++ 使用示例
开发语言·c++
不相心 -w-1 小时前
现代C++——智能指针
开发语言·c++
Ivanqhz2 小时前
php7 闭包实现
开发语言·后端·rust·php
weixin_440784119 小时前
【HandlerThread实现原理】
android·java·开发语言
天空'之城9 小时前
C 语言工业级通用组件手写 24:互补滤波
c语言·开发语言·互补滤波·嵌入式算法·工业级组件