LeetCode算法题191:位1的个数
前言
第一次尝试在算法题中使用与进行(&)位运算,一般多次使用过右移>>,左移<<,异或^这三种。
简单说下与运算(&)原理:1 1为1 其余为0。简单来说只有两个数比较都为1的情况才会为1,其他情况为0。
需要注意的是这题仅仅使用>>是不够的,因为>>仅仅只能满足非负数情况,如果为负数,最高位符号位为1。
原因:>>是舍弃最低位,高位使用符号位补充,这种情况使用>>会发生死循环,舍弃低位后补充符号位1,导致超时。需要使用无符号右移>>>让用0补充。
参考:负雪明烛详解位运算191
方法1-循环遍历
死循环代码
//leetcode submit region begin(Prohibit modification and deletion)
public class Solution {
// you need to treat n as an unsigned value
public int hammingWeight(int n) {
int count =0;
while (n != 0) {
count += n & 1;
n >>= 1;
}
return count;
}
}
//leetcode submit region end(Prohibit modification and deletion)
在知道原理后自然就能写出正确的代码,只需要将>>改为>>>即可。(顺便贴一下吧)
正确解法1
//leetcode submit region begin(Prohibit modification and deletion)
public class Solution {
// you need to treat n as an unsigned value
public int hammingWeight(int n) {
int count =0;
while (n != 0) {
count += n & 1;
n >>>= 1;
}
return count;
}
}
//leetcode submit region end(Prohibit modification and deletion)
方法2-去尾1
在了解过上面方法后,我们可以有更优解的方法,通过删除二进制末尾的1的思路下进行。
原理是通过n&(n-1)让n自动消去最后一个1来计数,具体实现原理还是推荐看负雪明烛详解位运算191
时间复杂度(logn),空间复杂度(1)
//leetcode submit region begin(Prohibit modification and deletion)
public class Solution {
// you need to treat n as an unsigned value
public int hammingWeight(int n) {
//计数器
int count = 0;
while(n!=0){
n &=n-1;
count++;
}
return count;
}
}
//leetcode submit region end(Prohibit modification and deletion)