第一题:将数字变成 0 的操作次数
将数字变成 0 的操作次数
LeetCode 1342:
描述:
给你一个非负整数 num ,请你返回将它变成 0 所需要的步数。 如果当前数字是偶数,你需要把它除以 2 ;否则,减去1 。
解题思路:
1.此题分为两种情况,一个是偶数情况,一个是奇数情况.
2.在偶数情况下要除以2, 可以用到移位运算中右移 >>1.
3.在奇数情况下要减去1, 可以用到位运算中的异或 ^1.
4.判断偶数的办法,可以用到位运算中的与运算 &1,当&1等于0的时候即是偶数.
画图解析:
次数 | 数字 | 奇偶性 | 根据奇偶性除减 |
---|---|---|---|
① | 14 | 偶数 | 14 / 2 = 7 |
② | 7 | 奇数 | 7 - 1 = 6 |
③ | 6 | 110 >> 1 = 11 | 6 / 2 = 3 |
④ | 3 | 奇数 | 3 - 1 = 2 |
⑤ | 2 | 10 >> 1 = 1 | 2 / 2 = 1 |
⑥ | 1 | 奇数 | 1 - 1 = 0 |
次数 | 判断奇偶性 | 奇数异或/偶数右移 | 注解 |
---|---|---|---|
① | 1110 & 1 ==0 | 1110 >> 1 = 111 | (二进制111 == 十进制 7) |
② | 111 & 1 != 0 | 111 ^ 1 = 110 | (二进制110 == 十进制6) |
③ | 110 & 1 == 0 | 110 >> 1 = 11 | (二进制 11 == 十进制 3) |
④ | 11 & 1 != 0 | 11 ^ 1 = 10 | (二进制 10 == 十进制 2) |
⑤ | 10 & 1 == 0 | 10 >> 1 = 1 | (二进制 1 == 十进制 1) |
⑥ | 1 & 1 != 0 | 1 ^ 1 = 0 | (二进制 0 == 十进制 0) |
代码实现:
class Solution {
public int numberOfSteps(int num) {
int count = 0;
while(num != 0){
if((num & 1)==0){
//偶数情况
num = num >> 1;
}else{
//奇数情况
num = num ^1;
}
count++;
}
return count;
}
}
第二题:两整数之和
两整数之和
LeetCode 371:
描述:
给你两个整数 a 和 b ,不使用 运算符 + 和 - ,计算并返回两整数之和。
解题思路:
1.不使用+和-求两整数之和.所以使用位运算解题
2.此题要考虑两种情况
①不进位的情况
②进位的情况
3.不进位的加法可以使用异或 ^ 运算
4.进位的情况可以使用 & 表示需要进位的地方,左移 <<1表示进位后的数字大小
画图解析:
代码实现:
class Solution {
public int getSum(int a, int b) {
while(b != 0){
//ret表示需要进位的值
int ret = (a & b) << 1;
//a表示不需要进位的值
a = a ^ b;
//b=ret 如果b为0,a即为需要求的值
//如果b不为0,则再进入循环 用^运算进行加法
b = ret;
}
return a;
}
}
第三题:位1的个数
位1的个数
LeetCode 191:
描述:
编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为 ‘1’ 的个数(也被称为汉明重量)。
解题思路:
1.观察
n & (n-1)
这个代码可以把 n 的二进制中,最后一个出现的 1 改写成 0。
2.循环操作 记录循环次数,就是1的个数.
画图解析:
代码实现:
public class Solution {
public int hammingWeight(int n) {
int count = 0;
while(n != 0){
n = n & (n - 1);
count++;
}
return count;
}
}