唯一一个重复值
1-1000这1000个数放在含有1001个元素的数组中,只有唯一的一个元素值重复,其它均只出现一次。每个数组元素只能访问一次,设计一个算法,将它找出来;不用辅助存储空间,能否设计一个算法实现?
1,2,3…k, k, …n
异或:A^A=0,A^A^B^C^C=B,这样可以消掉多余的元素,但是只用这个两个k会消掉,不能满足获取k值的需求,所以我们应该先进行1~1000进行异或
(1^2^3^k^ k^n)^(1^2^3^…^n)这样其余的都会成对消掉,最后剩下的是k。
原理:异或操作相当于非进位加法,如果两个相同的值,在二进制情况下0位和0位异或得0,1位和1位异或得0,所以所有的值全为0,但是两个不同的值,进行异或操作时0位和1位不是一一对应的,所以一定不为0
数字二进制中的1的个数
直接统计1的个数
//设数字为n
cnt=0;
while(n){
if(n&1){
cnt++;
}
n>>1;
}
在代码中轮循环令数字n和1做按位与运算,如果n的二进制末尾为1,cnt++,每轮循环后让n右移一位
每次消除最低位
cnt=0
while(n){
cnt++;
n = n & (n-1)
}
原理:
每次进行n & (n-1)操作都会将n的最后一位1消除
举例:
二进制数:n=10110, n-1=10101, n & (n-1)=10100
判断一个数是否为2的整数次方
问题分析:如果一个数是2的整数次方,那么他的二进制表示一定只有一位是1,其他位全是0。
问题转换:是否为2的整次方->二进制形式只有一位为1->采用消除最低为1的位的方式是否只能执行一次->n & (n-1)==0?
(n-1)& n==0
二进制奇偶位对调
问题:将整数n的二进制形式奇数位和偶位数对调
ou = n & 0xaaaaaaaa;
ji = n & 0x55555555;
n = (ou >> 1) ^(ji << 1)
假设奇数位用x表示,偶数位用y表示有二进制数
n = x y x y x y x y
n & 0 1 0 1 0 1 0 1 = 0 y 0 y 0 y 0 y
n & 1 0 1 0 1 0 1 0 = x 0 x 0 x 0 x 0
(n & 0 1 0 1 0 1 0 1 )<<1=y 0 y 0 y 0 y 0
(n & 1 0 1 0 1 0 1 0 )>>1=0 x 0 x 0 x 0 x
((n & 0 1 0 1 0 1 0 1 )<<1)^((n & 1 0 1 0 1 0 1 0 )>>1)=y x y x y x y x