芝士算法(位运算)

关于位运算的使用 可以从 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;
    }
相关推荐
何以解忧,唯有..9 分钟前
Redis 过期事件监听:原理与实战
java
weixin_3077791316 分钟前
C++代码实现MATLAB中的ode45函数功能
开发语言·c++·算法·matlab
风中的小熊生气20 分钟前
Spring Boot 面试知识(二):分层、IoC、异常、配置与 Redis
java·springboot
泡茶喝茶写代码20 分钟前
量化数据开发实战系列(第 25 篇):基金基础接口实战:基金列表、ETF-LOF 分类、基金概况、净值数据
java·数据库·人工智能·python·mysql
不穿鞋的懒羊羊41 分钟前
dfs深度优先搜索
算法
contro1_h1 小时前
关于ArcGIS许可管理器服务无法启动的问题
经验分享·笔记·学习方法
是立不是利1 小时前
大文件导致请求被拒的连锁反应
开发语言·前端·javascript
OYYHXPJR1 小时前
【算法】区间重叠模板和矩形重叠模板
算法
shehuiyuelaiyuehao1 小时前
算法46,分治快排,排序数组
java·算法·排序算法·排序
圣保罗的大教堂1 小时前
leetcode 3483. 不同三位偶数的数目 简单
leetcode