描述
这是一篇面对初级coder的题解。
知识点:二进制基础知识,位运算操作
难度:一星
题解
题目:输入一个整数,输出该数32位二进制表示中1的个数。其中负数用补码表示。
本题主要考察计算机数据存储的基本知识
首先是对于正数 考的是二进制到十进制的转化 我们平时的数是十进制 计算机中存储的是二进制
由于负数用补码表示 所以,可统一按无符号整型处理,或者加上2^32 使其变成正数(python整数无长度限制 自动匹配)
二进制补码:有符号数的负数的补码是 其正数的反码+1
方法一:进制转化基础知识
在进制转化中,可以使用短除法,即“二除取余法”。
如把给定的十进制数29除以2,商为14,所得的余数1是二进制数的最低位的数码,再将14除以2,商为7,余数为0。再将7除以2,商为3,余数为1,再将3除以2,商为1,余数为1,再将1除以2,商为0,余数为1是二进制数的最高位的数码。
此方法适用于多种语言
c++版
class Solution { public: int NumberOf1(int n) { unsigned int un=(unsigned int) n; //强制类型转换,解决补码 int answer=0; //记录答案 //开始短除 while(un>1){ if (un%2==1) answer++; //对应位有1 un=un/2; } if (un == 1) //最后的余数还要再处理一下 answer++; return answer; } };
运行时间: 2 ms 占用内存:512K
python版
# -*- coding:utf-8 -*- class Solution: def NumberOf1(self, n): # write code hereclass Solution { if(n<0): un=n & 0xffffffff #强制类型转换,解决补码 else: un=n answer=0 #记录答案 #开始短除 while(un>1): if (un%2==1): answer+=1 #对应位有1 un=un//2 #除法 ‘//’ 表示整除 if (un == 1):#最后的余数还要再处理一下 answer+=1 return answer
运行时间: 54 ms 占用内存:6884K
方法二:C位操作
C可以提供位操作
基于此 有如下方法 比较烧脑 尽力解释
惊喜解法:把一个整数减去1之后再和原来的整数做与运算,得到的结果相当于把整数的二进制表示中最右边的1变成0。
故
class Solution { public: int NumberOf1(int n) { //从右开始 逐位归零 int count = 0; while(n){ n &= (n - 1); count++; } return count; } };
运行时间: 12 ms 占用内存:516K
或者采用分治的思想 思路独特
class Solution { public: int NumberOf1(int n) { int temp = n; temp = (temp & 0x55555555) + ((temp & 0xaaaaaaaa) >> 1); temp = (temp & 0x33333333) + ((temp & 0xcccccccc) >> 2); temp = (temp & 0x0f0f0f0f) + ((temp & 0xf0f0f0f0) >> 4); temp = (temp & 0x00ff00ff) + ((temp & 0xff00ff00) >> 8); temp = (temp & 0x0000ffff) + ((temp & 0xffff0000) >> 16); return temp; } };运行时间: 5 ms 占用内存:512K
方法三:字符串处理 基于python
python具有强大的字符处理能力
class Solution: def NumberOf1(self, n): # write code hereclass Solution { if(n<0): n=n & 0xffffffff #强制类型转换,解决补码 return bin(n).count("1")
运行时间: 39 ms 占用内存:4308K
总结
适合的代码干适合的事情 ,c++的位操作,python的字符处理,各有特色
扩展
类似这种的数据逻辑 还有bitmap
就是这种类型题目的进阶版
可以很好的处理这些数据 本题也可以像下面这样用bitset来解
class Solution { public: int NumberOf1(int n) { bitsets(n); return s.count(); } };