-
位运算:&(与) | (或) ^(异或)
异或: 相同位0 , 不同为1
与: 都为1,结果为1, 只要有一个为0,结果是0
或: 只要有一个为1,结果是1, 都为0, 结果为0
例:10 & 21 –> 二进制运算 = 0
-
移位运算:
二进制: 最高位; 符号位: 0: 正 1: 负
左移,右移
左移: << 例如: 10<<1 高位去掉, 低位补0
n<<m –> n * 2的m次方 10<<1 –> 10 * 2的1次方 = 20
右移: >> >>> 把低位去掉, 高位补
>>
: 有符号位右移: 如果是正数, 高位补0 如果是负数, 高位补1
>>>
: 无符号位右移: 正数/负数, 高位补0
正数右移: m>>n m>>>n m / 2的n次方
原码:对于8位二进制来说,在数值前直接加一符号位的表示法。
补码:正数的反码与原码相同;负数的反码,符号位为“1”,数值部分按位取反。
反码:正数的补码和原码相同;负数的补码则是符号位为“1”,数值部分按位取反后再在末位(最低位)加1,也就是“反码+1”。
例子:给你一个整数数组 nums ,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次 。请你找出并返回那个只出现了一次的元素。
1、遍历每一个数组里的数的32位二进制数,分别存到新的数组里并相同位数相加
2、把新数组里的每一个数取余3,得到仅出现一次的数的二进制数
具体实现代码:
public class Test2 {
public static void main(String[] args) {
int[] nums={2,2,3,2};
System.out.println(singleNum(nums));
}
public static int singleNum(int[] nums) {
int[] count = new int[32];
for (int num:nums) {
for (int i = 0; i < 32; i++) {
count[i] += (num >> i) & 1;
}
}
int result=0;
for (int i = 0; i < count.length; i++) {
result|=(count[i]%3)<<i;
}
return result;
}
}
-
count[i]%3
:取count[i]
除以3的余数,这可以确保结果在0到2之间。 -
<<i
:将上一步的结果左移i
位。这相当于将每个余数的位值按照数组索引的顺序进行左移。 -
result|=
:使用位或运算符将上一步的结果与result
进行按位或操作,并将结果赋值给result
。
通过这个循环,result
变量将包含所有余数按位左移后的结果。这种操作通常用于将多个数字的某一位的状态合并到一个整数变量中。