最强解析面试题:二进制中 1 的个数「建议收藏!炸!」
Posted 魏小言
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最强解析面试题:二进制中 1 的个数「建议收藏!炸!」相关的知识,希望对你有一定的参考价值。
最强解析面试题:二进制中 1 的个数「建议收藏!」
文章讲解 “ 二进制中 1 的个数 ” 经典面试题,包含思路及源码,及解惑!
题目
输入一个整数,输出该数二进制表示中 1 的个数。其中负数用补码表示。
数据范围:2^ 32
示例1
输入:
3
返回值:
2
思路
运用位运算
依次判断二进制数末尾是否为 1 ,时间复杂度是二进制位数。
位运算 (>>、&):二进制数与 1 做 & 运算,每次右移一位,直至数值为 0。
例子: 2
0010 & 0001 = 0000 ;
2 >> 1 = 0001;
0001 & 0001 = 0001;
0001 >> 1 = 0;
& 运算次数为 2 ,结果为 1 的为一次,故 2 二进制中 1 的个数为 1。
代码
package main
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* @param n int整型
* @return int整型
*/
func NumberOf1( n int ) int {
// write code here
var m int32 = int32(n)
var res int
var flag int32 = 1
for flag != 0{
if m&flag != 0{
res++
}
flag<<=1
}
return res
}
运行结果
运行时间:4ms
超过90.00% 用Go提交的代码
占用内存:1347KB
超过36.86%用Go提交的代码
运用 n 与 n-1 二进制之间的数据关系
n 与 n-1、n+1、之间相差 1 ,二进制表现为有效位 1 之后取反。n & (n-1)可消掉 n 最地位有效 1 ,时间复杂度为二进制数中 1 的个数。
例子:2
2 & 1 = 0010 & 0001 = 0000 「把 0010 最低位 1 消除」
& 运算次数为 1,故 2 二进制中 1 的个数为 1。
代码
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* @param n int整型
* @return int整型
*/
func NumberOf1( n int ) int {
// write code here
var m int32 = int32(n)
var res int
for m !=0{
m&=(m-1)
res++
}
return res
}
运行结果
运行时间:2ms
超过64.87% 用Go提交的代码
占用内存:860KB
超过62.53%用Go提交的代码
Q&A
负数问题
有同学会疑问:负数怎么办?负数使用补码和正数不一致啊,是不是对负数需要进行额外的处理?
答案是,不用。正数存储其实也是补码,只不过和自身一样而已。
位移运算
注意:Goland 中无 “无符号左右移”,Java 等其它语言支持
若用 Java 实现,则思路一中可直接 无符号右移 N 即可,无需像 Go ,转弯思路去右移 Flag。
类型问题
注意:Goland 中 int 类型,有多种 int8\\int16\\int32….,单独只写 int,会自动根据系统默认,故这里需要根据题目区间特写 int32
边界问题
题目中已经指出为 int32 类型,需要考虑越界问题。
方案一中的
if m&flag != 0
不能调整为 m&flag == 1 或者 res+=m&flag,因为存在正负符号位,负数的符号位要算进去。
附录
诡异的问题背后,往往是低级的错误!
以上是关于最强解析面试题:二进制中 1 的个数「建议收藏!炸!」的主要内容,如果未能解决你的问题,请参考以下文章