常用符号
- & 与:两个位都为1,结果才为1
- | 或:两个位都为0,结果才为0
- ^ 异或:两个位相同为0,不相同为1
- ~ 取反
- << 左移:左移若干位,高位丢弃,低位补0
- 右移:右移若干位,低位丢弃,高位补0或者符号位(取决于编译器)
常用的位运算操作
- x&1 :判断奇偶,若结果为1,则为奇数,否则为偶数
- x = x & (x-1): 清除最低位的1
- abc = acb = a(bc):异或运算的交换/结合律
- a^a=0:任何数与自身做异或运算,结果为0
- a^0=a:任何数与0做异或运算,结果为自身
相关题目
Leetcode(191):位1的个数
![image-20201110090655013](https://i.loli.net/2020/11/10/4guqs7eHLNkGBbY.png)
利用 x=x&(x-1),可以不断地清除最低位的1,直到x所有位都为0
代码如下:(Javascript)
/**
* @param {number} n - a positive integer
* @return {number}
*/
var hammingWeight = function(n) {
let count=0
while(n!==0){
n = n & (n-1)
count++
}
return count
};
LeetCode(231):2的幂
![image-20201110091028534](https://i.loli.net/2020/11/10/KjkaZdD4cmEQJhy.png)
对于2的整数幂来说,他们的二进制表达式都只有1位为1
因此,作一次 x=x&(x-1)操作,再判断x是否为0即可
代码如下:(Javascript)
/**
* @param {number} n
* @return {boolean}
*/
var isPowerOfTwo = function(n) {
if(n<=0){
return false
}
n=n&(n-1)
return n===0 ? true : false
};
LeetCode(136):只出现一次的数字
![image-20201110091348157](https://i.loli.net/2020/11/10/UcMIHKieJSxONlF.png)
方法一:哈希表/集合
集合的常用方法:
- 创建一个新的空集合:var s = new Set()
- 查找集合中是否有某个元素:s.has(value)
- 向集合中添加新元素:s.add(value)
- 从集合中删除某元素:s.delete(value)
遍历数组,判断当前元素是否在集合中
若不在,则将其放入集合中
若在,则将其删除
最后取出集合中唯一的一个元素即可
这种方法使用了额外的空间,并不是最优解
方法二:异或运算
题目告诉我们,给定的数组一定是由n对元素和一个落单的元素组成的
假设有2m+1个元素,那么对他们都进行异或运算
由于任何数与自身异或 结果都为0,因此前2m个数的运算结果为0
第2m+1个数 与0异或 结果为自身
代码如下:(Javascript)
/**
* @param {number[]} nums
* @return {number}
*/
var singleNumber = function(nums) {
let res=nums[0]
for(let i=1;i<nums.length;i++){
res=res^nums[i]
}
return res
};