芝士算法(位运算)

关于位运算的使用 可以从 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;
    }
相关推荐
凯酱10 小时前
MyBatis 中 OGNL 的使用:从入门到实战
java·tomcat·mybatis
ting945200015 小时前
Humalike X Hermes 深度技术剖析:单指令注入群聊社交智能的底层架构、算法与跨 IM 平台实现
人工智能·算法·架构
Data_Journal15 小时前
用于网页抓取的 Node-unblocker
大数据·开发语言·数据库·python·scrapy
吴声子夜歌15 小时前
Java面试——算法
java·算法·面试
evans在进步16 小时前
LeetCode 64:最小路径和——Java 原地动态规划详解
java·leetcode·动态规划
豆角焖肉16 小时前
SSM 聚合项目搭建:多 Maven 模块项目
开发语言·python·pycharm
Frank_refuel16 小时前
【C++八股】面向对象
开发语言·c++
h_a_o777oah16 小时前
【图论】Tarjan 缩点:解决有向图中环的问题
c++·算法·图论·acm·强连通分量·缩点·tarjan
Tisfy16 小时前
LeetCode 1386.安排电影院座位:哈希表+位运算
算法·leetcode·散列表·题解·哈希表
Nil20817 小时前
leetcode 199二叉树的右视图
算法·leetcode·深度优先