Java 位元運算2-LeetCode 201 Bitwise AND of Numbers Range

來源:互聯網
上載者:User

標籤:

在Java位元運算總結-leetcode題目博文中總結了Java提供的按位元運算操作符,今天又碰到LeetCode中一道按位操作的題目

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

For example, given the range [5, 7], you should return 4.

題意:

給出m和n,將m到n之間所有的數字與一遍返回結果(包括m和n)

解題思路:

題目乍一看很簡單嘛,迴圈遍曆m到n按位與一遍返回結果就完了啊,但是將這種解法放入LeetCode會發現逾時,那麼就需要我們去總結規律。

例如題目給出的5,6,7二進位

0101   0110   0111

通過觀察我們會發現我們只要看數位高位即可,後面的數字會相互約掉

再比如

011000  0110001  0110010 0110011

我們發現貌似只要查看所有數位高k位即可

再比如

01100  01101 01110  01111  10000

我們比較發現如果m和n的位元不相同就會返回0

規律如下:

給出m和n,求出m和n相同的高k位(這裡m和n為整型變數,那麼按照32位來看待,前面的0也算作高位比較),那麼保留高k為其餘位置0即為最後結果。

代碼如下:

一開始我選擇從低位遍曆,記錄需要捨棄的低l位

代碼1

 1     public int rangeBitwiseAnd(int m, int n) { 2         if (n == m) 3             return m; 4         int h = 0; 5         int l = 0; 6         int mm = m; 7         while (m > 0 || n > 0) { 8             if ((m & 1) == (n & 1)) { 9                 m >>= 1;10                 n >>= 1;11                 ++h;12             }13             else {14                 m >>= 1;15                 n >>= 1;16                 l += h;17                 ++l;18                 h = 0;19             }20         }21         if(h==0)return 0;22         return mm & (0x7fffffff << l);23     }

 

通過後查看代碼其實直接從高位開始遍曆到第一個不相同的位停下即可找到高k位,代碼如下

代碼2

1     public int rangeBitwiseAnd2(int m, int n) {2         if(m==n) return m;3         int i;4         for(i = 31;i>0;i--){5             if((m&(1<<i))!=(n&(1<<i)))6                     break;7         }8         return m&(~((1<<i+1)-1));9     }

代碼簡潔了很多,也比原來的快了很多

 

題目再次利用了Java中的移位操作,記錄下做題中遇到的二進位的幾個問題:

1.整數x求-x,從二進位角度看是將x按位取反加1

2.左移正負數都是低位補0,右移正數高位補0負數補1,而如果使用Java無符號右移>>>則正負高位都補0

3.將整數按照二進位整個翻轉可以利用類似歸併排序的分治思想

  (1) 整數32為分成16和16先翻轉一下

  (2) 再翻轉前16位中的前8位和後8位,再翻轉後16位中的前8位和後8位

  。。。以此類推,總共需要Log232 = 5次

代碼如下:

1     public int reverseBit(int n) {2         n = ((n & 0xffff0000) >>> 16) | ((n & 0x0000ffff) << 16);3         n = ((n & 0xff00ff00) >>> 8) | ((n & 0x00ff00ff) << 8);4         n = ((n & 0xf0f0f0f0) >>> 4) | ((n & 0x0f0f0f0f) << 4);5         n = ((n & 0xcccccccc) >>> 2) | ((n & 0x33333333) << 2);6         n = ((n & 0xaaaaaaaa) >>> 1) | ((n & 0x55555555) << 1);7         return n;8     }

注意這裡是將整個32位全部翻轉,相當於32位倒過來看。

舉例,按照4位來看

1110

(1)將前2位和末2位翻轉 10  11

(2)將第一部分對調,第二部分對調得到結果  01 11

 

 

Java 位元運算2-LeetCode 201 Bitwise AND of Numbers Range

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.