这里写目录标题

  • 一、常(装)见(逼)的位操作
    • 先看几个有意思的位操作:
    • 1、判断奇数偶数
    • 2、交换两个数字
    • 3、找出没有重复的数字
    • 4、m的n次方
    • 5、判断一个数是不是二的指数
    • 6、找出不大于N的最大2的幂指数
  • 二、leetcode解题
    • 136.只出现一次的数字(简单)
    • 191.位1的个数(简单)

看完本文,可以顺便解决leetcode以下两个题目:
136.只出现一次的数字(简单)
191.位1的个数(简单)

一、常(装)见(逼)的位操作

先看几个有意思的位操作:

或操作 | 和空格将英文字符转换为小写,小写本身还是小写

(‘a’ | ’ ') = ‘a’
(‘A’ | ’ ') = ‘a’

与操作 & 和下划线将英文字符转换为大写,大写本身还是大写

(‘b’ & ‘’) = ‘B’
(‘B’ & '
’) = ‘B’

n&(n-1) 消除数字 n 的二进制表示中的最后一个 1

异或^和空格进行英文字符大小写互换;判断异号

(‘d’ ^ ’ ') = ‘D’
(‘D’ ^ ’ ') = ‘d’
x^y < 0;异号,否则同号

下面我们从简单开始,一步一步的实现复杂的位运算~

1、判断奇数偶数

看到这个,你肯定觉得很简单,然后随手写下:

if (n % 2 == 0)
{   // 偶数
} else {    // 奇数
}

其实使用位运算,可以这样写

if ( n & 1 == 1)
{// 奇数
} else {// 偶数
}

因为如果一个二进制表示偶数的话

偶数的最后一位肯定是0;

奇数的最后一位肯定是1;

2、交换两个数字

这个也是很常见的操作,很简单的就可以写下来:

temp = x;
x = y;
y = temp;

但是如果在实际工作中,遇到不借助辅助空间,依旧让你去交换两个数字呢?
这个时候,位运算的优势就体现出来了
位运算实现如下:

x = x^y
y = x^y
x = x^y

看的第一眼,肯定很懵~ 啥玩意儿这是

首先,我们需要知道两个个基础的公式:

n^n =0; 即相同的两个数异或结果是0
n^0 = n;一个数和0异或的结果是本身

所以,上面展开一下,就是

x = x^y
y = x^y^y = x^0 = x
x = x^y = x^y^x = x^x^y = 0^y = y
3、找出没有重复的数字

我们以上面的为基础,即相同的两个数异或结果是0;一个数和0异或的结果是本身
那我们就把这一些数字,遍历一遍,全部异或一下,不就OK了?

4、m的n次方

要求一个数m的n次方,但是不能使用POW函数,如何做?
不要使用 m x m x m x m x m~ 一直乘以n次,太low了;
时间复杂度就是 O(n)

使用阶乘,复杂度可以降低到O(log N)


int pow(int n){int sum = 1;int tmp = m;while(n != 0){if(n & 1 == 1){sum *= tmp;}tmp *= tmp;n = n >> 1;}return sum;
}

上述代码要是不理解二进制可能你就看不懂,这里我来举例解释一下

比如,求m的 5次方
我们把5用二进制表示,就是 0101,
从右往左看,第一个1 代表一个m
第二个1代表一个m x m x m x m ;
当二进制的这一位有1的时候,才把该位置代表的累乘的数算上,否则不算,继续看下一位的情况;

5、判断一个数是不是二的指数

如果一个数,是二的指数,那么它的二进制表示,肯定只有一个1
结合上面说到的:n&(n-1) 消除数字 n 的二进制表示中的最后一个 1

问题就好解决了

return (n > 0 ) && (n & (n - 1) == 0) ) ;
6、找出不大于N的最大2的幂指数

假设这个数是 19;
19用二进制表示就是 00010011
我们需要的结果就是 16 ;00010000
也就是 把 0010011,只保留最左边的一个1;
这个思路很简单,就是把最左边的1后面位,全部变成1;然后整体加1;由于加1之后会进位,所以在整体右移一位


应该怎么最左边的1后面位,全部变成1呢?

n |= n >> 1;
n |= n >> 2;
n |= n >> 4;

n |= n >> 1;
结果是最左边的1和其右边,也会有一个1;11

n |= n >> 2;
结果是最左边的11和其右边,也会有一个11;1111

n |= n >> 4;
结果是最左边的1111和其右边,也会有一个11;11111111

如此这样,后面就都变成1了,然后+1,右移一位就行

二、leetcode解题

136.只出现一次的数字(简单)

这个题刚刚上面说过了,全部都异或
直接上答案;

class Solution {public:int singleNumber(vector<int>& nums) {//异或int n=nums.size();int res=0;for(int i=0;i<n;i++){res^=nums[i];}return res;}
};
191.位1的个数(简单)


思路:
只需要记得:
n&(n-1) 消除数字 n 的二进制表示中的最后一个 1


class Solution {public:int hammingWeight(uint32_t n) {int res = 0;while (n != 0) {n = n & (n - 1);res++;} return res;}
};

位运算的那些奇技淫巧 | 掌(装)握(逼)必备,妙解两道算法题相关推荐

  1. 位运算的一些奇技淫巧

    位运算的一些奇技淫巧 位运算这种计算方式已经淡出我的编码习惯很久了,最近突然看见一篇推文在讲一些位运算在特殊场景下的奇妙作用,这显然勾起了阿光对于位运算的一泡浓厚的兴趣,于是我就搜集了一些位运算常用的 ...

  2. 【技巧总结】位运算装逼指南

    位算法的效率有多快我就不说,不信你可以去用 10 亿个数据模拟一下,今天给大家讲一讲位运算的一些经典例子.不过,最重要的不是看懂了这些例子就好,而是要在以后多去运用位运算这些技巧,当然,采用位运算,也 ...

  3. 【算法技巧】位运算装逼指南

    位算法的效率有多快我就不说,不信你可以去用 10 亿个数据模拟一下,今天给大家讲一讲位运算的一些经典例子.不过,最重要的不是看懂了这些例子就好,而是要在以后多去运用位运算这些技巧,当然,采用位运算,也 ...

  4. C++描述的位运算总结

    2021.05.07更新:添加异或运算的性质 2020.03.23更新:添加位运算符~的应用 2020.02.24更新:添加目录.调整格式. 2020.01.04更新:反码的缺点和使用,以及补码的优点 ...

  5. 漫画:位运算技巧整理汇总+一道被嫌弃的题目

    (这首歌挺喜欢的...分享出来) 今天是小浩算法"365刷题计划"第65天.这两天总有人来问我,做公众号赚了多少钱,或者就是怎么能和你一样,2个月就做到7000粉丝.说实话,至少到 ...

  6. 编程珠玑微信公众号-算法位运算

    [算法技巧]位运算装逼指南 编程珠玑 1周前 以下文章来源于帅地玩编程 ,作者帅地 帅地玩编程 本号专注于讲解数据结构与算法.计算机基础(如计算机网络+操作系统+数据库+Linux)等编程知识,期待你 ...

  7. java取二进制其中两位_Java:二进制(原码、反码、补码)与位运算(示例代码)...

    一.二进制(原码.反码.补码) 二进制的最高位是符号位("0"代表正数,"1"代表负数): Java中没有无符号数: 计算机以整数的补码进行运算: 1.  原码 ...

  8. java反码_Java:二进制(原码、反码、补码)与位运算

    一.二进制(原码.反码.补码) 二进制的最高位是符号位("0"代表正数,"1"代表负数): Java中没有无符号数: 计算机以整数的补码进行运算: 1.  原码 ...

  9. 算法题_位运算_9_出现一次的数字和出现k次的数字

    位运算 出现一次的数字和出现k次的数字 题目:出现k次和出现1次 描述:数组中只有一个数出现了1次,其他的数都出现了k次,请输出只出现1次的数. 第一次看到这道题,思考了一会,觉得可以使用Map集合来 ...

最新文章

  1. matlab 2012 vs2010混合编程
  2. [CLPR] 定位算法探幽 - 边缘和形态学
  3. 类似pyinstaller_Python 打包工具对比,Nuitka vs Pyinstaller
  4. python object类
  5. DataPipeline | PayPal庞姬桦:大数据在小微企业贷款上的运用
  6. Linux内存背后的那些神秘往事
  7. linux ll命令时间,linux ll显示时间格式
  8. HALCON 20.11:深度学习笔记(12)---语义分割
  9. Kubeadm installation
  10. ssh -CT -o BatchMode=yes 用户名@主机名
  11. 系统之美——系统思考与认识系统
  12. HDU1875prim算法求最小生成树
  13. 微信公众号——分享给朋友/分享至朋友圈(Vue)
  14. 在framework下新建系统api
  15. vscode文件图标消失
  16. 安装r 源代码 linux,在RStudio中从源代码安装R软件包时遇到问题-Ubuntu 16.04
  17. 安司密信服务器维护,安司密信好用吗?安司密信使用教程[多图]
  18. Docker与Dockerfile极简入门文档
  19. SIM卡状态字 SW1 SW2
  20. seo搜索引擎优化,seo搜索引擎优化名词解释

热门文章

  1. C++ Primer 5th笔记(chap 12 动态内存)allocator类
  2. 【Flask】ORM多对多关联关系
  3. C语言:构建一个二级链表并完成增删改查
  4. 用Go语言建立一个简单的区块链part2:Pow共识
  5. 校验数字签名防止apkP二次打包
  6. 2020-12-3(详解虚拟地址如何转化为物理地址)
  7. 【安全技术】红队之windows信息收集思路
  8. Windows保护模式学习笔记(七)—— PDEPTE
  9. 016 Android之NDK开发
  10. Linux 手动或自动挂载 NTFS 硬盘