探索JDK

探索Integer番外篇之Integer.numberOfLea

2018-10-25  本文已影响0人  苏小小北

1. 前言


通常我们经常会遇到这样的面试题:

       给定一个数字,求二进制最高位第一个1的位置。

其实在jdk已经有类似的实现了,下面就来看看大师的手笔。

2. 源码


这里并不是直接找第一个1的位置,而是统计最高位连续0的个数,实质上还是一样滴

    public static int numberOfLeadingZeros(int i) {
        // HD, Figure 5-6
        if (i == 0)
            return 32;
        int n = 1;
        if (i >>> 16 == 0) { n += 16; i <<= 16; }//1
        if (i >>> 24 == 0) { n +=  8; i <<=  8; }//2
        if (i >>> 28 == 0) { n +=  4; i <<=  4; }//3
        if (i >>> 30 == 0) { n +=  2; i <<=  2; }//4
        n -= i >>> 31;
        return n;
    }

对于32位int类型数字: 53242
二进制:0000 0000 0000 0000 1100 1111 1111 1010
(1)此时i为:0000 0000 0000 0000 1100 1111 1111 1010
先从32位即中间划分为两部门,0000 0000 0000 0000 和 1100 1111 1111 1010
如果最高位1在左边,那么 (i>>>16) 不等于0,继续下一步;
否则,最高位1在右边,那么发现前面有16个0,统计下,n += 16,除去前面16个0,i <<=16,继续下一步,(这步结束 n = 17)
(2)此时i为:1100 1111 1111 1010 0000 0000 0000 0000,统计前16位前导0的个数,所以,
从16位即中间划分为两部门,1100 1111 和 1111 1010 0000 0000 0000 0000
如果最高位1在左边,那么 (i>>>8) 不等于0,继续下一步;
否则,最高位1在右边,那么前面有8个0,统计学,n += 16,除去前面8个0,i <<= 16,继续下一步,
(3)同理直到 剩下最后一位。
如果 最后一位为0, 则返回n(因为n初始为1,不需要加最后一个);
否则 最后一位为1,n -= 1(因为n初始为1,最后一位不是0则减1)。

3.后言

时间复杂度只要O(log(32)),是不是比一位一位的比较(时间复杂度O(32)要快很多,而且代码还非常简洁、漂亮!

其他

本人也是在慢慢学习中,如有错误还请原谅、敬请指出,谢谢!

上一篇下一篇

猜你喜欢

热点阅读