有一个问题问:
我写了下面的解决方案,它工作正常。
int secondRightmostZeroBit(int n) {
return (int)Math.pow(2,Integer.toBinaryString(n).length()-1-Integer.toBinaryString(n).lastIndexOf('0',Integer.toBinaryString(n).lastIndexOf('0')-1)) ;
}
但是,下面是我投票也获得了最佳投票的解决方案,因为它只有几个字符可以满足要求,但我无法理解。有人可以解释一下位操纵如何帮助实现它。
int secondRightmostZeroBit(int n) {
return ~(n|(n+1)) & ((n|(n+1))+1) ;
}
最佳答案
考虑具有至少两个0位的某个数字。这是一个这样的数字示例,其中最右边的2个0位标记为(x ... x是我们不关心的位,它们可以是0或1,而1 ... 1是零或更大的序列最右边的0位的右边和左边的1位):
x...x01...101...1 - that's n
如果在该数字上加1,则会得到:
x...x01...110...0 - that's (n+1)
这意味着最右边的0位翻转为1
因此
n|(n+1)
将为您提供:x...x01...111...1 - that's n|(n+1)
如果将
1
添加到n|(n+1)
,则会得到:x...x100........0 - that's (n|(n+1))+1
这意味着第二个最右边的0位也会翻转为1
现在,
~(n|(n+1))
是y...y10.........0 - that's ~(n|(n+1))
其中每个y位是对应的x位的倒数
因此
~(n|(n+1)) & ((n|(n+1))+1)
给0...010.........0
其中唯一的1位在输入数字的第二个最右边的
0
位的位置。关于java - 位操作如何工作?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43510764/