LeetCode位运算(找出落单的数,二进制中1的个数,2的幂等)
文章目录
- 位运算理论+技巧介绍
- 1.与 &
- 2.异或 ^
- 3.移位及综合运用(指定位置)
- 4.同或
- 开撸
- 1. lc136 只出现一次的数字
- 2. lc137 只出现一次的数字II
- 3. lc260 只出现一次的数字III
- 4. lc268 丢失的数字
- 5. lc191. 位1的个数
- 6. lc 231 2的幂
- 7. lc1356 根据数字二进制下 1 的数目排序
- 推荐题目列表
位运算理论+技巧介绍
对于位运算的基础还有不熟悉的可以参考这篇:位运算操作符
1.与 &
表达式 | 含义 |
---|---|
(x & 1) == 1 | 奇数,等价于 x % 2 == 1 |
(x & 1) == 0 | 偶数,等价于 x % 2 == 0 |
x & (x - 1) | 把x最低位的二进制1给去掉 |
x & -x | 获取x最低位的1 |
2.异或 ^
性质 | 表达式 |
---|---|
交换律 | a ^ b ^ c <=> a ^ c ^ b |
任何数与 0 异或 为任何数 | 0 ^ n => n |
相同的数 异或 为0 | n ^ n => 0 |
3.移位及综合运用(指定位置)
功能 | 表达式 |
---|---|
x ∗ 2 n x * 2^n x∗2n | x << n |
x / 2 n x / 2^n x/2n | x >> n |
将 x 最右边的n位清零 | x & (~0 << n) |
获取 x 的第n位二进制值 | (x >> n) & 1(从低到高位算,从第0位开始) |
获取 x 的第n位的幂值 | x & (1 << n) |
仅将 x 的第n位 置为1 | x | (1 << n) |
仅将 x 第n位置为0 | x & (~(1 << n)) |
将 x 最高位至第n位(含)清零 | x & ((1 << n) - 1) |
将 x 的第n位至第0位(含)清零 | x & (~((1 << (n + 1)) - 1)) |
4.同或
注意Java中没有同或,可以用异或取反
开撸
1. lc136 只出现一次的数字
力扣136链接
描述:
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素
示例:
输入: [4,1,2,1,2]
输出: 4
Solution:
此题在哈希表中也出现过,leetcode哈希表(哈希集合,哈希映射)
当时第一反应肯定是用HashSet的去重性
但是如果想要线性复杂度,就要想到用位运算。利用的就是异或的性质!
public int singleNumber(int[] nums) {int res=0; // 0与任意数异或为任意数// 对每个数进行相互异或,相同的全变成了0for(int n:nums)res^=n;// 最后只剩下那个只出现一次的数字return res;}
2. lc137 只出现一次的数字II
力扣137链接
描述:
给你一个整数数组 nums ,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次 。请你找出并返回那个只出现了一次的元素。
示例:
输入:nums = [0,1,0,1,0,1,99] 输出:99
Solution:
与上题很相似,但又觉得有些困难。当然,可以用哈希的方法(关于次数的题目大多和哈希有关)
还是从原始出发,依次计算最终答案的各个二进制位,一张图表明:
1.对于出现三次的数字,各位出现的次数都是3的倍数
2.统计所有数字的各二进制位中1的个数,并对3取余,结果位只出现一次的数字
3.对于数组中的每一个元素 x,我们使用位运算(x >> i) & 1
得到 x 的第 i 个二进制位(将第 i 位移到最低位与1相与,得到结果,因为1和0 和1 相与 为其自身)
4.将它们相加再对 3取余,得到的结果一定为 0 或 1,即为答案的第 i 个二进制位
代码:
public int singleNumber(int[] nums) {// 初始化一个数组,用来记录结果的各个二进制位int[] tmp = new int[32];// 统计所有数字的各个二进制位的个数for(int num:nums){for(int i=0;i<32;i++){// 将第 i 位移到最低位与1相与,得到结果if(((num>>i)&1)==1)tmp[i]++;}}// ans 位最终结果int ans=0;for(int i=0;i<32;i++){// 对于各个位不为0的if ((tmp[i] % 3 & 1) == 1) {// 将二进制转化位十进制,1<<i=2^i表示权重ans+= (1 << i);}}return ans;
}
稍微改进一下,不用辅助空间,直接处理:
public int singleNumber(int[] nums) {int ans = 0;for (int i = 0; i < 32; ++i) {int total = 0;for (int num: nums) {total += ((num >> i) & 1);}if (total % 3 != 0) {ans |= (1 << i);}}return ans;}
3. lc260 只出现一次的数字III
力扣260链接
描述:
给你一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。你可以按 任意顺序 返回答案。
示例:
输入:nums = [1,2,1,3,2,5] 输出:[3,5]
Solution:
4. lc268 丢失的数字
力扣268链接
描述:
给定一个包含 [0, n] 中 n 个数的数组 nums ,找出 [0, n] 这个范围内没有出现在数组中的那个数。
示例:
输入:nums = [3,0,1] 输出:2
Solution:
此题与lc136 有异曲同工之妙,只需要多想一步
将这n个数与1~n 这n+1个数放在一起,共2n+1个数一起异或,最后的结果就是缺失的数
public int missingNumber(int[] nums) {int res = 0;for(int i=0;i<nums.length;i++){res ^= i;res ^= nums[i];}// 这里如果一开始的res初始化为数组长度,那最后输出就直接resreturn res^nums.length;
}
5. lc191. 位1的个数
描述:
编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为 ‘1’ 的个数(也被称为汉明重量)
示例:
输入:00000000000000000000000000001011
输出:3
Solution:
利用最开始总结的技巧:n&(n-1) 去除二进制的低位1来计算二进制的1
public int hammingWeight(int n) {int count=0;while(n!=0){n &= (n-1);count++;}return count;}
6. lc 231 2的幂
力扣231链接
描述:
给你一个整数 n,请你判断该整数是否是 2 的幂次方。如果是,返回 true ;否则,返回 false 。
示例:
输入: n = 16 输出: true
Solution1:
和上一题有异曲同工之妙
因为2的幂次方的二进制只有1位是1,所以把最低位去掉之后就成了0。利用上面提到的 n & (n-1)
public boolean isPowerOfTwo(int n) {return n>0 && ((n & (n-1))==0);}
Solution2:
利用n & (-n) 可以获取最低位的1
public boolean isPowerOfTwo(int n) {return n > 0 && (n & -n) == n;}
7. lc1356 根据数字二进制下 1 的数目排序
力扣1356链接
描述:
给你一个整数数组 arr 。请你将数组中的元素按照其二进制表示中数字 1 的数目升序排序。
如果存在多个数字二进制中 1 的数目相同,则必须将它们按照数值大小升序排列。
请你返回排序后的数组。
示例:
输入:
Solution:
推荐题目列表
题号 | 难度 |
---|---|
easy |
链接:https://leetcode.cn/problems/power-of-two/solution/5chong-jie-fa-ni-ying-gai-bei-xia-de-wei-6x9m/
LeetCode位运算(找出落单的数,二进制中1的个数,2的幂等)相关推荐
- 位运算:找出唯一成对的数、找出落单的数
1.找出唯一成对的数 题目: 1- 1000这1000个数放在含有1001个元素的数组中,只有唯一的一个元素值重复,其它均只出现一次.每个数组元素只能访问一次,设计一个算法,将它找出来;不用辅助存储空 ...
- 《剑指offer》-- 把数组排成最小的数、丑数、二进制中1的个数、表示数值的字符串、替换空格
一.把数组排成最小的数: 1.题目: 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个.例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为 ...
- 【LeetCode】剑指 Offer 15. 二进制中1的个数
[LeetCode]剑指 Offer 15. 二进制中1的个数 文章目录 [LeetCode]剑指 Offer 15. 二进制中1的个数 一.逐位判断 二.巧用 n&(n−1) 一.逐位判断 ...
- 剑指 Offer 15. 二进制中1的个数 + 191. 位1的个数(n(n-1)实例)
一.题目:剑指 Offer 15. 二进制中1的个数 请实现一个函数,输入一个整数(以二进制串形式),输出该数二进制表示中 1 的个数.例如,把 9 表示成二进制是 1001,有 2 位是 1.因此, ...
- 判断32位整数二进制中1的个数
在面试中被问到这一题:判断32位无符号整数二进制中1的个数,虽然不难,但要求层层优化.现在整理一下: 1.基本思路: #include <iostream> using namespace ...
- 《LeetCode力扣练习》剑指 Offer 15. 二进制中1的个数 Java
<LeetCode力扣练习>剑指 Offer 15. 二进制中1的个数 Java 一.资源 题目: 编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为 ...
- [剑指offer][JAVA]面试题第[15]题[二进制中1的个数][位运算]
[问题描述][简单] 请实现一个函数,输入一个整数(无符号数),输出该数二进制表示中 1 的个数.例如,把 9 表示成二进制是 1001,有 2 位是 1.因此,如果输入 9,则该函数输出 2.示例 ...
- 剑指Offer - 面试题15. 二进制中1的个数(位运算)
1. 题目 请实现一个函数,输入一个整数,输出该数二进制表示中 1 的个数.例如,把 9 表示成二进制是 1001,有 2 位是 1.因此,如果输入 9,则该函数输出 2. 示例 1: 输入:0000 ...
- 位运算之二进制中1的个数
本篇文章主要详解位运算的相关问题,以及解析python语言在求解该问题上的不方便. 涉及知识点: 1.原码,补码,反码的知识 2.与,或,非,异或,左移,右移,负数右移的相关知识 3.python数据 ...
最新文章
- Form表单提交前进行JS验证的3种方式
- 构建ASP.NET MVC5+EF6+EasyUI 1.4.3+Unity4.x注入的后台管理系统(61)-如何使用框架来开发?...
- 分析型数据仓库中读写分离的实现
- linux i o的使用情况,Linux下使用iostat 监视I/O状态
- 玩玩短视频平台和网课平台开发1——腾讯云对象储存COS的初步配置
- QQ小工具网页版源码
- Spring MVC异常处理 - @ ControllerAdvice,@ ExceptionHandler,HandlerExceptionResolver
- 使用Timer执行定时任务
- Qt官网变更【2012】
- ThinkPHP admin.php后台登录
- 写, 读sdcard目录上的文件
- 安装conntrack-tools
- 解决Hbuliderx的代码不能自动补全的问题
- 2017-2018论文更新
- 办公搜索利器UTOOLS-基于EVERYTHING的文件快速搜索软件
- LineageOS的代码下载、编译及真机运行
- linux文本编辑器
- 有同学问我Java工程师怎么入门?我马上甩出C认证模拟测试推荐给他!
- 2019第五届中国诗歌春晚致敬先贤
- 微信小程序 Basic Auth 前后端restful api进行身份验证
热门文章
- Pandas知识点-详解聚合函数agg
- android差分升级原理,BigNews Android 增量更新框架差分包升级 @codeKK c开源站
- 【论文笔记】Urban change detection for multispectral earth observation using convolution neural network
- 核心交换机、汇聚交换机、接入交换机的概念
- (2022版)一套教程搞定k8s安装到实战 | Ingress
- 算法笔记——曼哈顿距离,切比雪夫距离,曼哈顿距离之和 P3964 [TJOI2013]松鼠聚会
- 【NeurIPS2022】Cross Aggregation Transformer for Image Restoration
- Linux 启动nginx服务报错nginx: [error] open() /home/tool/nginx/logs/nginx.pid failed (2: No such file or
- 【效率】好用到爆!GitHub 星标 32.5k+的命令行软件管理神器,功能真心强大!...
- slice手环 android数据,迈欧slice手环使用感受 | 迈欧slice手环怎么样_什么值得买...