Given a positive integer, output its complement number. The complement strategy is to flip the bits of its binary representation.
Note:
- The given integer is guaranteed to fit within the range of a 32-bit signed integer.
- You could assume no leading zero bit in the integer’s binary representation.
Example 1:
Input: 5 Output: 2 Explanation: The binary representation of 5 is 101 (no leading zero bits), and its complement is 010. So you need to output 2.
Example 2:
Input: 1 Output: 0 Explanation: The binary representation of 1 is 1 (no leading zero bits), and its complement is 0. So you need to output 0.
题意:给定一个整数,输出另一个整数。对这个数的要求是原数转换成二进制后,从高向低第一个1开始按位取反所得到的数。
基本思路:
1.最常规想法:定义1个长度为32的int(bool/char/type) 数组,把原数二进制展开,然后数0,并在数组中相应的位置上写1,到最后一个1为止。然后再把数组变成一个二进制数,然后就能得到想要的数。代码如下(找最后一个1的方式有点蠢,不仅适合正数也适合负数):
1 int findComplement(int num) { 2 int a[32] = {0};//定义数组 3 int cnt = 0; 4 while(num) 5 { 6 a[cnt++] = (num%2)^1;//保存元素 7 num/=2; 8 } 9 while(a[cnt] == 0 && cnt > 0)//找数组最后的位置 10 cnt--; 11 cnt ++; 12 int i = 0; 13 int ret = 0; 14 while(i<=cnt) 15 { 16 ret += (1<<i)*a[i];//把数组转化成数 17 ++i; 18 } 19 return ret; 20 }
2. 用上面的方法是3ms并不慢。当然并不是没有简单的方法,这题看上去就像按位取反,然而按位取反并不太可行,因为5取反等于-6,仍然要去掉高位的1,才能得到想要的数。最后仍然要去统计高位有多少个1,保存在一个数组或数中再进行操作。
3. 不过保存在1个数中,从占用的空间上看多少能让我们觉得更加欣慰一点,多少有一点优化好过没有优化,既然都要把这个数转化成二进制,那我们可以顺手构造一个新的数,让他的每一位都为1,并且位数和原来的数相等,然后用这个数和原来的数直接异或并返回。这种查位的方法只适合正数(题中也说的是正数)
1 int findComplement(int num) { 2 int i = 0,ret = 0,tmp = num; 3 while((tmp/=2)!=0) 4 ret += 1<<i++; 5 ret+=1<<i;//因为/=2先进行后判断,所以要后加一次 6 return ret^num;//这里也可以改成ret-num,当然这并不是位操作实现减法的原理 7 }
当然结果仍然是3ms 代码看上去倒是简洁了不少。
更简洁的方法就是思路2,我自己想了半天觉得没有特别简单的方法就没写
以下来自LeetCode lzl124631x137大神,适合正数和负数
1 class Solution { 2 public: 3 int findComplement(int num) { 4 unsigned mask = ~0;//将掩码各位全设1 5 while (num & mask) mask <<= 1;//掩码左移确定num位数 6 return ~mask & ~num;//取反再取与 7 } 8 };
还有一个比较奇特的方法,由于给的是正整数所以这种方法是可行的的,如果包含负数这种将不可行
1 int findComplement(int num) { 2 int mask = num; 3 mask |= mask >> 1; 4 mask |= mask >> 2; 5 mask |= mask >> 4; 6 mask |= mask >> 8; 7 mask |= mask >> 16; 8 return num ^ mask; 9 }
有兴趣的可以去看下他的解释:https://discuss.leetcode.com/topic/74897/maybe-fewest-operations。侵删。