Fork me on GitHub

中等-201-数字范围按位与

LeetCode201
视频解析
给定范围 [m, n],其中 0 <= m <= n <= 2147483647,返回此范围内所有数字的按位与(包含 m, n 两端点)。
示例 1: 
输入: [5,7]
输出: 4
示例 2:
输入: [0,1]
输出: 0

该题在于找出m和n的公共前缀,在按n的位数往后面补齐0.
m到n之间的数都有该前缀,则按位与操作使得这些前缀保持不变。而前缀后一位数m为0,n为1,无论m、n该位后面的数字为多少,
在m到n之间一定存在一个数,其在前缀后面的数为1000... 该数与m按位与得到(前缀0000...)
寻找公共前缀有两个方法,和(计数二进制数字中1的个数)该题类似。

  1. 位移
    m和n同时向右位移,直到m、n相等时,余下的为前缀。
    public int rangeBitwiseAnd(int m, int n) {
        int count = 0;
        while(m!=n){
            count++;
            m >>= 1;
            n >>= 1;
        }
        n <<= count;
        return n;
    }
  1. BK算法
    n=n&(n-1)使得n将最右边的1转化为0。当n<=m时,n前缀后面的数已经全为0.直接返回.
    public int rangeBitwiseAnd(int m, int n) {
        while(m<n)
            n&=(n-1);
        return n;
    }
posted @ 2020-07-15 10:01  Faded828x  阅读(85)  评论(0编辑  收藏  举报