天天看點

LeetCode-190. 颠倒二進制位(java)

一、前言🔥

👨‍🎓作者:bug菌

✏️部落格:CSDN​、掘金等

💌公衆号:​​猿圈奇妙屋​​

🚫特别聲明:原創不易,轉載請附上原文出處連結和本文聲明,謝謝配合。

🙏版權聲明:文章裡可能部分文字或者圖檔來源于網際網路或者百度百科,如有侵權請聯系bug菌處理。

《每日一題LeetCode》給重新捯饬起來,隻為幫助小夥伴們,能順利上岸,收到自己心儀的offer,面試第一關, 就是算法題。因為我始終堅信,變強絕對不是一朝一夕,而是貴在長久堅持,持之以恒。是以,趕緊跟着bug菌的步伐卷起來吧⏰,變強從這一刻開始➕🧈。

       小夥伴們在批閱文章的過程中如果覺得文章對您有一絲絲幫助,還請别吝啬您手裡的贊呀,大膽的把文章點亮👍吧,您的點贊三連(收藏⭐️+關注👨‍🎓+留言📃)就是對bug菌我創作道路上最好的鼓勵與支援😘。時光不棄🏃🏻‍♀️,創作不停💕,加油☘️

二、題目描述🔥

題目:

        颠倒給定的 32 位無符号整數的二進制位。

提示:

        請注意,在某些語言(如 Java)中,沒有無符号整數類型。在這種情況下,輸入和輸出都将被指定為有符号整數類型,并且不應影響您的實作,因為無論整數是有符号的還是無符号的,其内部的二進制表示形式都是相同的。

        在 Java 中,編譯器使用二進制補碼記法來表示有符号整數。是以,在 示例 2 中,輸入表示有符号整數 -3,輸出表示有符号整數 -1073741825。

具體請看如下示例:

示例 1:

輸入:n = 00000010100101000001111010011100
輸出:964176192 (00111001011110000010100101000000)
解釋:輸入的二進制串 00000010100101000001111010011100 表示無符号整數 43261596,
     是以傳回 964176192,其二進制表示形式為 00111001011110000010100101000000。      
LeetCode-190. 颠倒二進制位(java)

示例 2:

輸入:n = 11111111111111111111111111111101
輸出:3221225471 (10111111111111111111111111111111)
解釋:輸入的二進制串 11111111111111111111111111111101 表示無符号整數 4294967293,
     是以傳回 3221225471 其二進制表示形式為 10111111111111111111111111111111 。      
LeetCode-190. 颠倒二進制位(java)

提示:

  • 輸入是一個長度為​

    ​32​

    ​ 的二進制字元串

題目來源:LeetCode原題位址

題目難度:⭐⭐

三、思路分析🔥

        一看到這題,整個人第一眼傻了,這讀完一遍題,不知所雲,于是乎接着理題。仔細看下示例,其實就是道翻轉題,隻不過它是32位值,我為了讓大家看的更清楚,給大家舉個簡單的十進制示例,比如:

輸入:1234  輸出:4321

輸入:-1234  輸出:-4321

        然後遇到這種題,其實解法很常見,但唯獨需要注意的一點就是負數和0為字首的題,但是今天這題明顯是不需要考慮這種特例所帶來的問題,顯然也好處理,了解了其實就容易。 

解題思路1-颠倒法:

  1. 我們首先初始化一個存放結果的整數a。
  2. 然後定義一個循環來控制次數,每次都對n進行一次右移。
  3. 然後将最後一位取出,向左移動(31-i)位,将其加入到結果集中。
  4. 循環結束,即得題解值。

解題思路2-分治法

        其實這題也可以使用分治法來進行解題,其方法核心就是通過或運算實作位的互換。我們先将32位分為兩部分進行順序交換,也就是對半颠倒,比如将前16位與後16位進行一個交換,之後前半部分的8位與後半部分的8位進行交換,依次類推,直到最後兩位交換完順序,最終順序就完成了颠倒。

        然後我還想到了,其實也可以使用雙指針法來解題,比如左右指針分别從二進制序列的兩端往中間移動,然後交換位置,直到雙指針碰面,則退出循環即可。

四、算法實作🔥

颠倒法-AC代碼

具體算法代碼實作如下:

public class Solution1 {
        public int reverseBits(int {

            //首先初始化一個存放結果的整數a
            int a = 0;
            //開始周遊
            for (int i = 0; i <= 31; i++) {
                //取出最後一位進行左移。
                a += ((1 & (n >> i)) << (31 - i));
            }
            return      
LeetCode-190. 颠倒二進制位(java)

分治法-AC代碼

具體算法代碼實作如下:

public class Solution {
    
    //窮舉4類。
    private static final int M1 = 0x55555555; 
    private static final int M2 = 0x33333333;
    private static final int M4 = 0x0f0f0f0f; 
    private static final int M8 = 0x00ff00ff;

    public int reverseBits(int {
        n = n >>> 1 & M1 | (n & M1) << 1;
        n = n >>> 2 & M2 | (n & M2) << 2;
        n = n >>> 4 & M4 | (n & M4) << 4;
        n = n >>> 8 & M8 | (n & M8) << 8;
        return n >>> 16 | n << 16;
    }
}      
LeetCode-190. 颠倒二進制位(java)

五、總結🔥

leetcode送出運作結果截圖如下:

LeetCode-190. 颠倒二進制位(java)
LeetCode-190. 颠倒二進制位(java)

 複雜度分析:

  • 時間複雜度:O(1)
  • 空間複雜度:O(1)
位運算分治法-leetcode送出運作結果截圖如下:      
LeetCode-190. 颠倒二進制位(java)

 複雜度分析:

  • 時間複雜度:O(1)
  • 空間複雜度:O(1)

       總言而之,仔細審題,就可以發現一點,該題其實主要是考察了 位運算的知識,用其他的解題思路,個人感覺有點繞,是以對位運算需要一點深入了解對于解該題就比較輕松了。是以平時要多積累一些解題模型,這樣對于不同的題型用對解題模型是最直接有效的。

       再者,解題道路千萬條,歡迎小夥伴們腦洞大開,如果你們有啥更好的想法或者思路,歡迎評論區告訴我哦,大家一起互相借鑒互相學習,方能成長的更快。

       好啦,以上就是本期的所有内容啦,咱們下期見咯。

  六、熱門推薦🔥

  1. ​​leetcode-9.回文數​​
  2. ​​leetcode-1.兩數之和​​
  3. ​​leetcode-13.羅馬數字轉整數​​
  4. ​​leetcode-14.最長公共字首​​
  5. ​​leetcode-20.有效的括号​​
  6. ​​leetcode-21.合并兩個有序連結清單​​
  7. ​​leetcode-26. 删除有序數組中的重複項​​

七、文末🔥

《每日一題LeetCode》,帶着你一塊兒刷題,專欄每一篇都附帶詳細解法,手把手帶你解題。

        一個人刷可能會覺得很累很難堅持,但是一群人刷就會覺得它是一件很有意義的事兒,互相督促互相鼓勵,一起變強。

       我是bug菌,一名想走👣出大山改變命運的程式猿。接下來的路還很長,都等待着我們去突破、去挑戰。來吧,小夥伴們,我們一起加油!未來皆可期,fighting!

最後送大家兩句話,與諸君共勉!

☘️做你想做的人,沒有時間限制,隻要願意,什麼時候都可以start,

🍀你能從現在開始改變,也可以一成不變,這件事,沒有規矩可言,你可以活出最精彩的自己。

LeetCode-190. 颠倒二進制位(java)

💌如果文章對您有所幫助,就請留下您的贊吧!(#^.^#);

💝如果喜歡bug菌分享的文章,就請給bug菌點個關注吧!(๑′ᴗ‵๑)づ╭❤~;

繼續閱讀