zoukankan      html  css  js  c++  java
  • 奇妙的位运算(二)

    上篇的链接为:http://www.cnblogs.com/jiu0821/p/4677184.html

    这次是偶然看到一个题目,很好玩,便记在这里吧!

    Bitwise AND of Numbers Range

    给出一个范围,[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 };
  • 相关阅读:
    字符串
    完全背包
    背包2
    0-1背包
    生日劲歌会
    设计照明系统
    宝岛探险
    汉诺塔问题
    并查集 黑帮危机
    数塔问题
  • 原文地址:https://www.cnblogs.com/jiu0821/p/4931996.html
Copyright © 2011-2022 走看看