位运算
今天的刷题内容是:
剑指 Offer 15. 二进制中1的个数
剑指 Offer 65. 不用加减乘除做加法
因为题目涉及到位运算,所以特此来复习一下位运算和它的应用。
位运算符的分类
下图为位逻辑运算结果:
解释
图中第三列A&B代表与运算,第四列A|B代表或运算,第五列是异或运算,最后一列是非运算。我们对每个运算逐个分析。
与运算:当所有元素均为1时,结果为1,否则为0。
举例: 1100&1000 =1000
或运算:只需一个元素为1时,结果为1,否则为0。
举例:0100 | 1000=1100
异或运算: 当元素相异(10 或01)时,结果为1,否则为0。
举例:11111 ^ 10110 = 01001
非运算:元素取反。
举例:~1011 = 0100
位逻辑运算的逻辑结果
位逻辑的运算结果中的0改为false,1改为true,则构成了上图。
位移运算
左移 <<
左移当符号未改变时,进行了 ×2的运算
高位舍去,低位补0,会改变符号
右移 >>
右移进行了 ÷2的运算
高位看原符号,正数补0,负数补1(为了不使符号改变),低位舍去
无符号右移 >>>
高位补0,低位舍去,无符号右移之后数字变为非负数。
总结:
左移、无符号右移不考虑正负,右移考虑正负。
算法结合
二进制中1的个数
与运算 n&1 ==1
OFFER65 : 不用加减乘除做加法
异或:0^1=1,相当于无进位的求和
与: 1&1=1;1&0=0;0&0=0;即都为1的时候才为1,正好可以模拟进位数的情况,相当于求每位的进位数
65:数组中出现数字的次数
// 找不同,异或
for(int num: nums){
sum ^= num;
}
// 得到sum的二进制的1的最低位index
index = sum & (-sum);