给定范围 [m, n],其中 0 <= m <= n <= 2147483647,返回此范围内所有数字的按位与(包含 m, n 两端点)。
示例 1: 输入: [5,7] 输出: 4
示例 2: 输入: [0,1] 输出: 0
这个题精髓在于n的二进制位比m二进制最左边的1高时,&的结果必然为0,受此思想启发,给出两种解答方案
class Solution { private: int getLen(int m) //获取二进制的位数 { int len = 0; while(m) { len++; m>>=1; } return len; } public: int rangeBitwiseAnd(int m, int n) { if(getLen(m) != getLen(n)) return 0; int numRes = n; for(int i = n-1 ; i >= m; i--) { if(numRes == 0) return 0; numRes &= i; } return numRes; } };1、获取二进制的位数,从大到小不断进行与运算
class Solution { public: int rangeBitwiseAnd(int m, int n) { //n&(n-1)会把最后一个1后面所有位都置为0,有点类似找m和n二进制的公共前缀 int cnt = 0; //记录右移的次数 while(m != n) //直到m和n相同 { if(m == 0) return 0; m >>= 1; n >>= 1; cnt++; } return m << cnt; } };2、二进制最高位相同时,这个1会保存,然后比较右一位,相同也保留… 所以只需要m n 同时右移到相等时 m n的值就是&后能保留的位数,然后左移回来就是最后的值。