【刷力扣】1342. 將數字變成 0 的操作次數

henFiu發表於2024-08-14

1342.將數字變成 0 的操作次數
這題是包含在“力扣新手村”裡的題,按直接模擬的方法來寫很簡單。
不過我一點兒都沒有想到位運算的寫法,看了看別人的題解,學習了一下下~

解法1:直接模擬

直接按題意模擬:
1.判斷num是否為0。
2.num不為0,進行一次操作:
(1)奇數:num = num - 1;
(2)偶數:num = num / 2;
3.再次執行1進行判斷,2進行操作(cnt++),直到num為0。

class Solution {
public:
    int numberOfSteps(int num) {
        int cnt = 0;
        while (num) {
            if (num % 2 == 0) num /= 2;
            else num -= 1;
            cnt++;
        }
        return cnt;
    }
};

時間複雜度:\(O(log num)\)
空間複雜度:\(O(1)\)

解法2:位運算1

其中:
num & 1:判斷num是否為奇數,如果為奇數,則進行一次操作,操作次數cnt加1。
cnt再次加1,num並作右移操作,即num >> 1(num / 2)。
多做了一次右移操作,所以要將cnt - 1。

class Solution {
public:
    int numberOfSteps(int num) {
        int cnt = 0;
        while (num) {
            cnt += (num & 1) + 1;
            num >>= 1;
        }
        return max(cnt - 1, 0);
    }
};

時間複雜度:\(O(log num)\)
空間複雜度:\(O(1)\)

解法3:位運算2

其中:
1.減去1的次數,即二進位制位中1的個數。
__bulitin_popcount
這個函式作用是返回輸入的二進位制表示中1的個數;如果傳入0則返回0。
2.除以2的次數,二進位制數長度減一,即最高位到最低位的距離。
__builtin_clz
這個函式作用是返回輸入數二進位制表示從最高位開始(左起)的連續的0的個數。

class Solution {
public:
    int numberOfSteps(int num) {
        if (num == 0) return 0;
        return 32 - __builtin_clz(num) - 1 + __builtin_popcount(num);
    }
};

時間複雜度:\(O(1)\)\(O(logW)\),其中W為32。
空間複雜度:\(O(1)\)

函式學習

1.__builtin_ctz

這個函式作用是返回輸入數二進位制表示從最低位開始(右起)的連續的0的個數。

2.__builtin_clz

這個函式作用是返回輸入數二進位制表示從最高位開始(左起)的連續的0的個數。

3.__builtin_ffs

這個函式作用是返回輸入數二進位制表示的最低非0位的下標,下標從1開始計數;如果傳入0則返回0。

4.__bulitin_popcount

這個函式作用是返回輸入的二進位制表示中1的個數;如果傳入0則返回0。

5.__bulitin_parity

這個函式作用是返回輸入的二進位制表示中1的個數的奇偶,也就是輸入的二進位制中1的個數對2取模的結果。

相關文章