标签:
上篇的链接为:http://www.cnblogs.com/jiu0821/p/4677184.html
这次是偶然看到一个题目,很好玩,便记在这里吧!
给出一个范围,[m, n](0 <= m <= n <= 2147483647),返回这些数字的与运算结果。
直接逐个做与运算,TLE,我们得发现高效解法。
我们把[0, 15]用二进制码表示出来:
0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 1 0 1 0 0 0 1 0 1 0 1 1 0 0 1 1 1 1 0 0 0 1 0 0 1 1 0 1 0 1 0 1 1 1 1 0 0 1 1 0 1 1 1 1 0 1 1 1 1
仔细看,几个连续的二进制码肯定会有相同的前缀(前缀长度可能为0),除了相同的前缀外,将之后的各位置为0即为所求。如何求解这个相同前缀?只需要m和n同时右移,直到两数相等为止:
1 class Solution { 2 public: 3 int rangeBitwiseAnd(int m, int n) { 4 int t=0; 5 while(m!=n){ 6 m>>=1; 7 n>>=1; 8 t++; 9 } 10 return m<<t; 11 } 12 };
或者:
1 class Solution { 2 public: 3 int rangeBitwiseAnd(int m, int n) { 4 if(m==n) return m; 5 int t=rangeBitwiseAnd(m>>1,n>>1); 6 return t<<1; 7 } 8 };
还有一种更巧妙的方法,将n的最右边的 1 bit 置为0,直到值不大于m即可:
1 class Solution { 2 public: 3 int rangeBitwiseAnd(int m, int n) { 4 while(m<n) n&=n-1; 5 return n; 6 } 7 };
标签:
原文地址:http://www.cnblogs.com/jiu0821/p/4931996.html