位运算基础

说到与(&)、或(|)、非(~)、异或(^)、位移等位运算,就得说到位运算的各种奇淫巧技,下面分运算符说明。

1. 与(&)

计算式 a&b,a、b各位中同为 1 才为 1,否则为0,a&1和a%2效果一样;来看两道典型的题目,第1道计算整数二进制中 1 的位数:

  1. //191. Number of 1 Bits
  2. int hammingWeight(uint32_t n) {
  3. ;
  4. ){
  5. n=n&(n-);
  6. ++res;
  7. }
  8. return res;
  9. }

n=n&(n-1)代表去掉整数n二进制中最左侧为 1 的位,例如n=12,则:

  1. n ->
  2. &
  3. n- -> 1 0
  4. ------------------
  5. 1 0

第2道判断一个数是否为4的乘方数(不能用loop解):

  1. //342. Power of Four
  2. bool isPowerOfFour(int num) {
  3. if(num==INT_MIN) return false;
  4. )) && (num&0x55555555);
  5. }

以上0x55555555的二进制表示为……01010101 (偶数位为0、奇数位为1),像这样tricky的数还有:

  1. (偶数位为1,奇数位为0
  2. (10每隔两位交替出现)
  3. (01每隔两位交替出现)
  4. (10每隔四位交替出现)
  5. (01每隔四位交替出现)

相关LeetCode题:

191. Number of 1 Bits  题解

201. Bitwise AND of Numbers Range  题解

 

2. 或(|)

计算式a|b,a、b各位中有一个为1则结果为1;来看一道题:有正整数n,求小于或等于n的2的最大乘方数(不能用loop解):

  1. int largest_power(ing N) {
  2. N = N | (N>>);
  3. N = N | (N>>);
  4. N = N | (N>>);
  5. N = N | (N>>);
  6. N = N | (N>>);
  7. )>>;
  8. }

看起来是不是相当tricky,其思路是用或运算将右边位数置为1,例如n=01010,通过或操作n变为01111,则n+1为10000,所求为01000;更详细解释见 这里

相关LeetCode题:

190. Reverse Bits  题解

3. 异或(^)

计算式a^b,a、b对应位相同为0,相异则为1;根据异或性质有a^a=0,a^0=a,利用该性质可解决136. Single Number:

  1. //136. Single Number
  2. int singleNumber(vector<int>& nums) {
  3. ;
  4. for(auto x:nums) res^=x;
  5. return res;
  6. }

相关LeetCode题:

136. Single Number  题解

461. Hamming Distance  题解

371. Sum of Two Integers  题解

260. Single Number III  题解

 

4. 位移

a<<1效果相当于a*2(不超出数值类型范围情况下),a>>1效果相当于a/2,位移常用于按位轮询。

相关LeetCode题:

405. Convert a Number to Hexadecimal  题解

 
逐位计算结果 

有意思的时当我们的目光放到bit的维度,一些问题可以按位来求解,例如169. Majority Element求数组中出现次数大于一半的数:

  1. //169. Majority Element
  2. int majorityElement(vector<int>& nums) {
  3. ,size=nums.size(),ret=;
  4. ;i<32;i++){
  5. ;
  6. ;j<size;j++){
  7. if(nums[j]&mask) count++;
  8. ){
  9. ret|=mask; //逐位计算结果break;
  10. }
  11. }
  12. mask<<=;
  13. }
  14. return ret;
  15. }

相关LeetCode题:

169. Majority Element  题解

421. Maximum XOR of Two Numbers in an Array  题解

使用bit表示数据

在一些场景下我们希望用bit来表示数据,或节省空间或利用bit的运算特性来表示状态转换。

相关LeetCode题:

289. Game of Life  题解

算法与数据结构基础 - 位运算(Bit Manipulation)的更多相关文章

  1. 算法与数据结构基础 - 堆(Heap)和优先级队列(Priority queue)

    堆基础 堆(Heap)是具有这样性质的数据结构:1/完全二叉树 2/所有节点的值大于等于(或小于等于)子节点的值: 图片来源:这里 堆可以用数组存储,插入.删除会触发节点shift_down.shif ...

  2. 算法与数据结构基础 - 广度优先搜索(BFS)

    BFS基础 广度优先搜索(Breadth First Search)用于按离始节点距离.由近到远渐次访问图的节点,可视化BFS 通常使用队列(queue)结构模拟BFS过程,关于queue见:算法与数 ...

  3. 算法与数据结构基础 - 哈希表(Hash Table)

    Hash Table基础 哈希表(Hash Table)是常用的数据结构,其运用哈希函数(hash function)实现映射,内部使用开放定址.拉链法等方式解决哈希冲突,使得读写时间复杂度平均为O( ...

  4. 算法与数据结构基础 - 二叉树(Binary Tree)

    二叉树基础 满足这样性质的树称为二叉树:空树或节点最多有两个子树,称为左子树.右子树, 左右子树节点同样最多有两个子树. 二叉树是递归定义的,因而常用递归/DFS的思想处理二叉树相关问题,例如Leet ...

  5. 算法与数据结构基础 - 分治法(Divide and Conquer)

    分治法基础 分治法(Divide and Conquer)顾名思义,思想核心是将问题拆分为子问题,对子问题求解.最终合并结果,分治法用伪代码表示如下: function f(input x size ...

  6. 算法与数据结构基础 - 双指针(Two Pointers)

    双指针基础 双指针(Two Pointers)是面对数组.链表结构的一种处理技巧.这里“指针”是泛指,不但包括通常意义上的指针,还包括索引.迭代器等可用于遍历的游标. 同方向指针 设定两个指针.从头往 ...

  7. 算法与数据结构基础 - 贪心(Greedy)

    贪心基础 贪心(Greedy)常用于解决最优问题,以期通过某种策略获得一系列局部最优解.从而求得整体最优解. 贪心从局部最优角度考虑,只适用于具备无后效性的问题,即某个状态以前的过程不影响以后的状态. ...

  8. 算法与数据结构基础 - 图(Graph)

    图基础 图(Graph)应用广泛,程序中可用邻接表和邻接矩阵表示图.依据不同维度,图可以分为有向图/无向图.有权图/无权图.连通图/非连通图.循环图/非循环图,有向图中的顶点具有入度/出度的概念. 面 ...

  9. 算法与数据结构基础 - 深度优先搜索(DFS)

    DFS基础 深度优先搜索(Depth First Search)是一种搜索思路,相比广度优先搜索(BFS),DFS对每一个分枝路径深入到不能再深入为止,其应用于树/图的遍历.嵌套关系处理.回溯等,可以 ...

随机推荐

  1. HDU 1533:Going Home(KM算法求二分图最小权匹配)

    http://acm.hdu.edu.cn/showproblem.php?pid=1533 Going Home Problem Description   On a grid map there ...

  2. aspnetcore 实现简单的伪静态化

    aspnetcore 实现简单的伪静态化 Intro 在我的活动室预约项目中,有一个公告模块,类似于新闻发布,个人感觉像新闻这种网页基本就是发布的时候编辑一次之后就再也不会改了,最适合静态化了, 静态 ...

  3. 分组在re模块中的使用

    import re #search s = "<a>wahaha</a>" #标签语言 html 和 web相关 ret= re.search(" ...

  4. 无法启动iis express web服务器解决

    VS2013 .VS2015 .VS2017调试出现无法启动iis express web服务器 最近自己老是遇到这个问题,天天如此,烦死人,网上答案繁多,但是都解决不了,也是由于各种环境不同导致的, ...

  5. Java学习笔记之---内部类

    Java学习笔记之---内部类 (一)成员内部类 内部类在外部使用时,无法直接实例化,需要借助外部类信息才能实例化 内部类的访问修饰符可以任意,但是访问范围会受到影响 内部类可以直接访问外部类的成员, ...

  6. tmux终端复用神器简单使用

    创建命名Tmux会话(tmux new -s session_name)tmux new -s session_name chongchong 暂退Tmux会话(Ctrl + a d)直接关窗口 返回 ...

  7. java算法题每日一练01,java入门简单算法题小练

    1.给数组做反序 public class Ak01 { public static void main(String[] args) { int[] a = new int[]{22,48,41,2 ...

  8. 个人永久性免费-Excel催化剂功能第89波-批量多图片转PDF

    前一篇展示了从PDF中提取到有用信息如图片.文本.表格等功能,部分人可能对自己手中的转PDF格式的保护性有所顾虑,此篇从反向角度,提供数据保护作用,让PDF文件的数据保护更彻底,让文本型的PDF文件彻 ...

  9. Hadoop之WritableComprale 排序

    Hadoop之WritableComprale 排序 Hadoop只对key进行排序 排序是 MapReduce 框架中最重要的操作之一.Map Task 和 Reduce Task 均会对数据(按照 ...

  10. 《C# 语言学习笔记》——目录

    C# 简介 变量和表达式 流程控制 3.1 布尔逻辑 3.2 goto语句 3.3 分支 3.4 循环 变量的更多内容 4.1 类型转换 4.2 复杂的变量类型 4.3 字符串的处理 函数 5.1 定 ...