常见位运算及其经典算法题(1)

常见位运算及其经典算法题(1)

位运算顾名思义,是对整数的二进制位直接进行操作的运算。由此很多算法便有了更优解,大大提高了效率。如果你之前没有接触过位运算或者淡忘了,这篇文章或许会对你很有帮助。

1.六大核心运算符

<<(左移运算符)

规则:左移n位,低位补0

例如:5的二进制为0101,5<<2即0101左移两位,变成010100,即20

所以5<<2==20
我们可以发现:根据二进制转十进制的计算,原数字二进制中整体往左移动n位,就是乘以2^n,所以左移运算符的重要用途就是快速计算乘2的幂。

>>(右移运算符)

规则:右移n位,高位补符号位

例如:5>>1,即0101右移两位,等于0010;

(-5)>>1:

5的二进制位0000 0101(原码),求负数的二进制规则就是它对应的正数取反 ,+1,即

取反:1111 1010;+1:1111 1011。即-5=1111 1011(8位)

所以右移一位即:1111 1101,把它转回十进制,即-1,取反

0000 0011等于3,而根据上文表粗的原则,1111 1101=-3,即-5>>1==-3

&(按位与运算符)

规则:两个整数的每一位二进制比较,两个中有0结果就是0,其他都是1

例如:5(0101)& 3(0011)== 1(0001)

同理>>可以计算x//2^n(向下取整)

||(按位或运算符)

规则:两个整数的每一位二进制比较,两个中有1结果就是1,其他都是0

例如:5(0101)|| 3(0011)== 7(0111)

^(按位异或运算符)

规则:相同位0,相反为1,无进位相加

例如:5(0101)^ 3(0011)== 6(0110)

~(按位取反运算符)

规则:0变1,1变0

2.位运算常用结论

  • 取出二进制第i位:(x >> i)& 1
  • 将第i位改成1:n = n | ( 1 << i )
  • 将第i位改成0:n = n & ( ~ ( 1 << i ) )
  • 提取二进制中最右侧的1:n & ( -n )
  • 将二进制中最右侧的1变成0:n & (n-1)
  • 异或运算律:a ^ 0 = a. a ^ a = 0. a ^ b ^ c=a ^ (b ^c)

3.经典例题

1.leetcode面试题 01.01. 判定字符是否唯一

这道题我们可以用set数据结构快速解决。但还有一种方法,便是位运算。

题中所给字母均为小写,所以一个符合条件的字符串最多包含a-z 26个英文字母。而整型有32位。我们可以从前往后遍历字符串,得出每个字符关于a的偏移量,将对应位的0变成1.代表此字母已经出现,如果后续再出现就返回false

cpp 复制代码
class Solution {
public:
   bool isUnique(string astr) {
       int flag=0;//每一位的0/1便是判断正误的关键
       for(auto e:astr)
       {
           int offset=e-'a';
           if(flag&(1<<offset))//判断此位是否已经为1
           {
               return false;
           }
           flag=flag|(1<<offset);//将此字母存入flag中
       }
       return true;
   }
};

2. leetcode371. 两整数之和

我们看到这道题后,就能大概率猜出是要用到位运算的知识点.

而这里便用到了异或^无进位相加的性质.

例如2^3==1(0001),异或以后惊奇的发现结果就是无进位相加后的结果,所以我们现在只需算出进位,再将两者异或,知道进位为0便可算出结果.

进位的表达式是(a&b)<<1.例如:

算到这里后,再将0001与0100异或得到0101,他俩的进位为0000,即0101就是结果5

cpp 复制代码
class Solution {
public:
    int getSum(int a, int b) {
        while(b!=0)
        {
            int x=a^b;//^的无进位相加
            unsigned int carry=(unsigned int)(a&b)<<1;//记录进位
            a=x;
            b=carry;
        }
        return a;
    }
};

今天就是这些东西。如有疑问,欢迎打在评论区。

主页还有更多优质内容OvO

相关推荐
Zevalin爱灰灰1 小时前
方法论——如何设计控制策略架构
算法·架构·嵌入式
wostcdk1 小时前
基础算法学习1
算法
Yzzz-F1 小时前
2026牛客寒假算法基础集训营1
算法
野犬寒鸦1 小时前
Java8 ConcurrentHashMap 深度解析(底层数据结构详解及方法执行流程)
java·开发语言·数据库·后端·学习·算法·哈希算法
兩尛1 小时前
155最小栈/c++
开发语言·c++
白太岁1 小时前
Muduo:(2) EPollPoller 实现 epoll 封装、 fd 事件监听与事件通知
网络·c++·网络协议·tcp/ip
m0_531237171 小时前
C语言-函数递归练习
算法
回敲代码的猴子1 小时前
2月18日打卡
算法
追随者永远是胜利者1 小时前
(LeetCode-Hot100)647. 回文子串
java·算法·leetcode·职场和发展·go