小夕:我先来说一下我的解法:
public class Solution {
public int NumberOf1(int n) {
String s=Integer.toBinaryString(n);
String[] split=s.split("");
int a=0;
for(int i = 0; i < split.length; i++) {
if (split[i].equals("1"))
{ a++; }
}
return a;
}
}
助教:对于一个数12,求它的二进制中有几个1。count代表它里面有几个1。 然后我将n和n-1的按位相与:
n是12,n-1是11,两者按位相与,n&n-1 = 8,n&n-1 它的二进制是1000。
到这里我们发现减1的结果是把最右边的一个1开始的所有位都取反了。也就是下图所示,全都取反了!
这个时候如果我们再把原来的整数和减去1之后的结果做与运算(也就是n&n-1),从原来整数最右边一个1那一位开始所有位都会变成0。如1100&1011=1000。也就是如下图所示: 也就是说,把一个整数减去1,再和原整数做与运算(也就是n&n-1),会把该整数最右边一个1变成0.也就是如下图所示,n=12变成了n&n-1也就是变成8,12是1100,8是1000,12的二进制中最右边的1变成了0也就是成为了8。 那么一个整数的二进制有多少个1,就可以进行多少次这样的操作。好的接下来,让n=n&n-1,也就是n=8了,那么n-1是7,来继续求n&n-1。 n继续和n-1按位相与得到的结果是0: 最后由于结果为0,所以结束,一共进行了两次这样的操作,所以12二进制中有两个1。
动画.GIF
public class Solution {
public int NumberOf1(int n) {
int count = 0;
while (n != 0) {
++count;
n = (n - 1) & n;
}
return count;
}
}
# -*- coding:utf-8 -*-
class Solution:
def NumberOf1(self, n):
# write code here
count = 0;
if n < 0:
n = n & 0xffffffff
while (n != 0):
count += 1
n = (n - 1) & n
return count;
class Solution {
public:
int NumberOf1(int n) {
int count = 0;
while (n != 0) {
++count;
n = (n - 1) & n;
}
return count;
}
};
<?php
function NumberOf1($n)
{
$count = 0;
if($n < 0){ // 处理负数
$n = $n&0x7FFFFFFF;
++$count;
}
while($n != 0){
$count++;
$n = $n & ($n-1);
}
return $count;
}
function NumberOf1(n)
{
// write code here
var count = 0;
while (n != 0) {
count++;
n = (n - 1) & n;
}
return count;
}
【助教解释一下】n = n & 0xffffffff,在Python中,数的大小是可以无限扩大的,不会像Java或c++中,数超过32位会溢出,而是继续扩张,所以对于一个负数而言,进行了这个操作,实际上是提取了负数的后32位(在计算机中以补码形式存在),前面的任意位呢,则变成了0,比如说 -1,一开始是 111.....(n个1)...11111111,进行与运算之后,得到,00....(n个0)....111111111(32个1),变成了含32个1的正数,然后就不用担心负数陷入死循环。
Copyright© 2013-2020
All Rights Reserved 京ICP备2023019179号-8