LeetCode 201. Bitwise AND of Numbers Range

[Med] LeetCode 201. Bitwise AND of Numbers Range

链接: https://leetcode.com/problems/bitwise-and-of-numbers-range/

题目描述:
Given a range [m, n] where 0 <= m <= n <= 2147483647, return the bitwise AND of all numbers in this range, inclusive.

给定范围 [m, n],其中 0 <= m <= n <= 2147483647,返回此范围内所有数字的按位与(包含 m, n 两端点)。

Example 1:

Input: [5,7]
Output: 4

Example 2:

Input: [0,1]
Output: 0


Tag: Bit-operation
解题思路
这道题目有点神奇,其实考察的是一种"推断能力"?题目告诉给我们两个数m和n. 让我们找到这两个数字之间所有数字进行AND操作之后的结果是什么。比如说题目的[5,7].对应的二进制数字是:
5 -> 101
6 -> 110
7 -> 111
上面三个数字取AND操作之后,只有每一位都为1的位置才是1,所以结果是"100" =4。

一开始我就是用了硬解的方法。从m位一位一位的或到n位。不出所料,TLE了。但是我一直没有想出来一个好的解法。后来看了答案,发现大家都是这样做的。
我们要找到m和n的最长前缀,这个最长的前缀就是最终的结果。
比如说上面这个例子,[5,7]之间只有最高位都是1,所以最终的结果就是100。
再举一个例子,[26, 30]的二进制如下所示。
26 -> 11010  
27 -> 11011  
28 -> 11100  
29 -> 11101  
30 -> 11110
相同的前缀只有最高位和次高位相同,所以结果就是"11000" -> 24
网上看了一圈之后发现只有解法,并没有说明为什么取m, n的最长的前缀可以达到寻找这之间数字和的原因。一下是我的看法。
我们考虑两个情况
(1). 跨区间的情况,比方说[3, 6],3是属于[2,4]这个区间的,所以是两位数。6是属于[4, 8]这个区间的。所以是三位数。在这两层之间,我们要经历从两位数变成三位数的跨度。这个跨度两端的两个数字AND操作后一定为0。比如说3和4,3 -> 11, 4 -> 100。所以任何情况下只要跨了二进制的一位,结果就会是0。这个和我们的代码操作逻辑一致。
(2). m和n都在一个区间之内。我们知道如果高位和低位都在一个区间之内的话。紧跟在相同prefix之后的低位会不断地变化,每一次增加1知道m变成n。在去掉相同的prefix之后,后面其实也可以看做是情况(1)的跨区间变化。比如说上面的[26, 30]这一个区间,在去掉相同的prefix之后,就变成了如下形式。
26 -> 11010 -> 010
27 -> 11011 -> 011
28 -> 11100 -> 100
29 -> 11101 -> 101
30 -> 11110 -> 110
也变成了跨区间的形式。所有后面这一段的AND操作之后会变成0。这也是我们为什么要找最长前缀和的目的。

解法一:
我们使用一个mask为整形最大数(全部位置都是1)。每一次我们向左移动一位,用mask和m和n的高位进行AND计算。直到找到最大的common prefix。
最后是低位和mask进行AND计算。

class Solution {
    public int rangeBitwiseAnd(int m, int n) {
        int mask =Integer.MAX_VALUE;
        while( (m &mask) != (n&mask)){
            mask = mask <<1;
        }
        return m &mask;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值