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取模的結果。