leetcode190 Reverse Bits

題目要求

Reverse bits of a given 32 bits unsigned integer.

For example, given input 43261596 (represented in binary as 00000010100101000001111010011100), 
return 964176192 (represented in binary as 00111001011110000010100101000000).

Follow up:
If this function is called many times, how would you optimize it?

你首先須要知道的事

這裏涉及了十進制和二進制之間轉化這個知識點。在數學中,咱們都是採用十進制進行計算,通俗說就是逢十進一。可是計算機沒有那麼多類型的信號來對應是十進制數中的十個數字,所以採用了二進制來進行計算。面試

二進制,也就是所謂的逢二進一,每一位上只有兩個數字,分別是0和1。每個十進制都有一個惟一的二進制數做爲對應。咱們先來看一下十進制數的計算,好比945等價於9*100+4*10+5*1,也就是9*10^2 + 4*10^1 + 5*10^0。同理咱們知道,二進制數011表明0*2^2 + 1*2^1 + 1*2^0也就是十進制的3。這樣,咱們知道如何將二進制數轉化爲十進制數。緩存

那麼計算機是怎麼進行計算的呢?計算機首先將十進制數轉化爲二進制數,再將二進制數根據需求進行計算。假設計算機須要計算3+6,那麼轉化爲二進制就是11+110,那麼計算機的計算流程以下。微信

1.對齊 在左側補零位使的兩個數字位數相同,所以就是 011+110
2.逢二進一 相似於十進制數的逢十進一,所以計算的結果爲 1001,轉化爲十進制數就是9

基於二進制的位計算上,除去加減乘除,計算機還定義了一些其餘的位運算符this

>> 將二進制數右移,左邊根據數字的正負形補0或者補1,正數補0,負數補1。
<< 將二進制數左移,右邊補0
>>> 將二進制數右移,左邊補0

在這些知識的基礎上,咱們再來看這道題目。spa

思路一:比特位移動

將比特位逆轉過來也就是將十進制數轉化爲二進制數,再從右往左得到每一位上的值,再將這個值添加至結果值中。設計

public int reverseBits(int n) {
        //得到最後一位的值
        int mask = 1;
        int result = 0;
        for(int i=0 ; i<32 ; i++){
            result <<= 1;
            result |= (n & mask);
            n >>= 1;
        }
        return result;
    }

思路二:屢次計算的話利用緩存提升銷量

爲了將比特位逆轉,意味着咱們至少須要32次循環才能將整個遍歷完成。那麼若是這個逆轉比特位方法會被調用屢次的話,咱們能夠使用一個Map來緩存已經遍歷過的狀況
可是,32位的重複值每每不多,所以咱們能夠將整數分解爲多個片斷存入緩存中,只要遇到重複的片斷,就能夠將已經獲得的結果返回給調用方。根據分治思想,逆轉32個比特位等價於分別將每8個比特位進行逆轉。所以咱們能夠將長度爲32的unsigned int拆解成4個長度爲8的byte。每8個byte對應的值能夠做爲片斷存在緩存中,只要遇到重複的片斷,就能夠直接返回。code

Map<Byte, Integer> cache = new HashMap<Byte, Integer>();
    public int reverseBits2(int n){
        byte[] bytes = new byte[4];
        for(int i = 0 ; i<4 ; i++){
            // 得到8位並轉換爲1個byte
            bytes[i] = (byte) ((n>>>(i*8)) & 0xff);
        }
        int result = 0;
        for(int i = 0 ; i<4 ; i++){
            result += reverseByte(bytes[i]);
            if(i<3) result<<=8;
        }
        return result;
    }
    
    public int reverseByte(byte b){
        Integer value = cache.get(b);
        if(value != null) return value;
        value = 0;
        for(int i = 0 ; i<8 ; i++){
            value += ((b>>>i) & 1);
            if(i<7) value <<= 1;
        }
        cache.put(b, value);
        return value;
    }

clipboard.png
想要了解更多開發技術,面試教程以及互聯網公司內推,歡迎關注個人微信公衆號!將會不按期的發放福利哦~教程

相關文章
相關標籤/搜索