java 求一个数的补数_476. 数字的补数 java

参考自:https://blog.csdn.net/midnight_time/article/details/79796968

给定一个正整数,输出它的补数。补数是对该数的二进制表示取反。

注意:

给定的整数保证在32位带符号整数的范围内。

你可以假定二进制数不包含前导零位。

示例 1:

输入: 5

输出: 2

解释: 5的二进制表示为101(没有前导零位),其补数为010。所以你需要输出2。

示例 2:

输入: 1

输出: 0

解释: 1的二进制表示为1(没有前导零位),其补数为0。所以你需要输出0。

答案是:

class Solution {

public int findComplement(int num) {

return (~num) & (Integer.highestOneBit(num) - 1);

//或 return (~num) & ((Integer.highestOneBit(num)<<1) - 1);

}

}

完全看不懂。

以上各个符号的作用:

/*

* 1) Integer.highestOneBit(num) :取num的二进制数最左边的最高位,且高位后面全部补零,

* 最后返回int型的结果。

* 2) -1:因为经过上面的步骤,只有最高位为 1 其余位都为 0 这样再减一 就会导致借位 直到借到最高位

* 结果得到 最高位为0 其余位都为1 相当于取反了

* 3) ~ :对一个数的二进制取反

* 4) &:对两个二进制数进行按位与运算,例 101 101 * & 010 & 111 * 得 000 得 101

*/

分析,经过1) 首先定义一个 int 型的num,在计算机中占2字节,1字节 = 8 位 ,也就是说, 5 在计算机中存储的方式是: 00000000 00000101 ,

Integer.highestOneBit(5):取5的不含前导位的二进制的最高位,即101  取1,其他位都补0;得到100;

2)100 减一之后变为 011 ,这时再和 ~num 进行与运算, 因为011 位数不够,所以需要填补0,即 00000000 00000011

3)~num 的意思就是取反,即得到 11111111 11111010    ;

4)运算:~num: 11111111 11111010

&       00000000 00000011

得     00000000 00000010    即十进制的 2

参考的文档写的很详细且风趣/

总结:很直白的一个思路就是 把整型数字转换为二进制形式,再将二进制数取反,但是要考虑到32位的二进制数除了将int目标数转换为二进制的低位  的左边的高位数上的0,因为这些0不能取反  不能作为结果计算进去;

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
假设有一个包含n个数字组,数字的范围为1到m,现在从这个组中随机抽k个数字这k个数字中至少有一个数字重复出现的概率。 这个问题可以使用概率论中的补集思想来解决。即先出这k个数字中没有数字重复出现的概率,然后用1减去这个概率即可得到至少有一个数字重复出现的概率。 假设我们选的第一个数字为x1,则后面选的k-1个数字中不能有x1,因此后面选数字的范围为1到m-1。如果我们选的第二个数字为x2,则后面选的k-2个数字中不能有x2,因此后面选数字的范围为1到m-2。以此类推,对于第i个数字,后面选数字的范围为1到m-i+1。 因此,选k个数字且没有数字重复出现的概率为: P1 = m*(m-1)*(m-2)*...*(m-k+1)/(m^k) 那么至少有一个数字重复出现的概率为: P2 = 1 - P1 Java代码实现如下: ```java public static double probability(int n, int m, int k) { double p = 1.0; for (int i = 1; i <= k; i++) { p *= (double)(m-i+1) / m; } return 1 - p; } ``` 其中,n为组长度,m为数字范围,k为选数字。 例如,如果我们有一个包含10个数字组,数字范围为1到100,现在从组中随机抽3个数字,那么至少有一个数字重复出现的概率为: ```java double p = probability(10, 100, 3); System.out.println(p); //输出0.264 ``` 因此,这个问题的答案是0.264。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值