某个数字进行位运算

将数字按位倒序

leetcode190 https://leetcode.com/problems/reverse-bits/

Reverse bits of a given 32 bits unsigned integer.
For example, given input 43261596 (represented in binary as 00000010100101000001111010011100), return 964176192 (represented in binary as 00111001011110000010100101000000).
Follow up:
If this function is called many times, how would you optimize it?
Related problem: Reverse Integer

思路:将数字倒叙,就是将左边位放到新数的右边位上去。直观想法就是,用1与原数,或新数并左移。再不断循环上述操作。

public int reverseBits(int n) {
    int rs = 0;
    for(int i = 0; i < 32; i++, n >>>= 1) rs = (rs << 1)|(1 & n);
    return rs;
}

问如何优化
思路:用交换的思想,如果是0与31位交换,1与30….也就是要进行32次移位和16次或运算。
而优化可以利用一个整体与一个整体交换来减少移动次数(类似希尔思想)
32位先将前16位与后16位交换,再将8位8位交换,再将4位4位交换,2位2位,1位1位。这样就减少至10次移位和5次或运算。
注:运算符优先级。。
+,-,*,/,++,– 大于 移位运算符 大于 & 大于 ^ 大于 |

public int reverseBits(int n) {
    n = n >>> 16 | n << 16;
    n = (n & 0xFF00FF00) >>> 8 | (n & 0x00FF00FF) << 8;
    n = (n & 0xF0F0F0F0) >>> 4 | (n & 0x0F0F0F0F) << 4;
    n = (n & 0xCCCCCCCC) >>> 2 | (n & 0x33333333) << 2;
    n = (n & 0xAAAAAAAA) >>> 1 | (n & 0x55555555) << 1;
    return n;
}

判断数字位中有多少个1

leetcode 191 https://leetcode.com/problems/number-of-1-bits/
剑指offer10_二进制中1的个数

Write a function that takes an unsigned integer and returns the number of1' bits it has (also known as the Hamming weight).
For example, the 32-bit integer11' has binary representation 00000000000000000000000000001011, so the function should return 3.

思路
有符号数右移并判断,会死循环:负数的二进制右移会在高位补1
一种高效方法:本身与本身-1相与。得到结果为最右边1的左边结果(1100 & 1000 —> 1000),不需要与32次,有多少1就与几次。

public int hammingWeight(int n) {
    int count = 0;
    while(n != 0){
        n &= (n-1);
        count ++;
    }
    return count;
}

另一种高效方法:运用整体计算方法
将每2位中1的个数保存在这2位上
将每4位中1的个数保存在这4位上
将每8位中1的个数保存在这8位上
将每16位中1的个数保存在这16位上
将每32位中1的个数保存在这32位上

public int hammingWeight(int n) {
    n = (n & 0x55555555) + (n >>> 1 & 0x55555555); 
    n = (n & 0x33333333) + (n >>> 2 & 0x33333333);
    n = (n & 0x0F0F0F0F) + (n >>> 4 & 0x0F0F0F0F);
    n = (n & 0x00FF00FF) + (n >>> 8 & 0x00FF00FF);
    n = (n & 0x0000FFFF) + (n >>> 16 & 0x0000FFFF);
    return n;
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值