学习按位与操作的一些心得

在LeetCode上做题时,有一道与按位与有关的题,如下:
【题目】
看到通过率有些纳闷
这里写图片描述
看题目也不是很难,感觉用一层循环就可以了
第一次尝试的代码:

    public static int rangeBitwiseAnd1(int m, int n) {
        int result = m;
        for (int i = m+1; i <= n; i++) {
            result = result&i;
            if (result==0) {
                break;
            }
        }
        return result;
    }

提交失败:Time Limit Exceeded
测试用例是:m=60000,n=2147483647
时间复杂度分析:一层循环O(n),按位与操作32位,常数级O(1);虽然时间复杂度是O(n),但是显然题目要求更加有效率的解法。参考讨论区的帖子,看到很好的例子。
这里写图片描述
分析思路:如下例子
5 — 0000 0101
6 — 0000 0110
7 — 0000 0111
4 — 0000 0100

1.在数字加1的时候,最低位会从0变成1或从1变成0,按位与结果必然是0;
2.对于8 — 0000 1000 最高位发生改变,那么其之下的位都变成0,那么在按位与过程中,除了最高位其之下的位都将变成0;
3.因此,只要是改变的位,按位与的结果必然是0;
4.数字m经历累加1到达n的过程,必然是从最低位开始改变,直到某个位置及这之上的位都不必再改变;
5.例如从5到7,第一位和第二位都做了改变,并不是只有第二位做了改变,因此一位二位都得0,而相同的没有改变的三位为原来的位数,1;
6.因此,只要找到m和n由最高位(相同)开始的连续的相同位数的片段保留,其余变为零即可。

算法:
1.i=0,右移零位开始判断,两个数相等,返回这个数;
2.i++,将不相等的低位右移,得到m和n由最高位(相同)开始的连续的相同位数的片段;
3.将m被右移的位数左移恢复为零,输出。
事件复杂度O(1)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值