1.位1的个数
191.位1的个数
法1:String法
public int hammingWeight(int n) {
int ret = 0;
String str = Integer.toBinaryString(n);
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) == '1') {
ret++;
}
}
return ret;
}
法2:按位与运算&与移位<< >> >>>
以前在博客写过这个:
笔试的时候想到的是左移右移,也想到了与运算,但就没有想到它们组合起来……
public int hammingWeight(int n) {
int ret = 0;
while (n != 0) {
if ((n & 1) == 1) {
ret++;
}
n >>>= 1;
}
return ret;
}
n&1经常用来n的奇偶性,是偶数则结果为0,奇数则结果为1。也可以用来获取最右边的位。
法3:改良位操作(布赖恩·克尼根算法)
public int hammingWeight(int n) {
int ret = 0;
while (n != 0) {
ret++;
n &= (n - 1);
}
return ret;
}
n&n-1作用是把最右边的1变成0
2.汉明距离
461.汉明距离
法1:
public int hammingDistance(int x, int y) {
int z = x ^ y;
int ret = 0;
while (z != 0) {
ret++;
z &= (z - 1);
}
return ret;
}
法2:
public int hammingDistance(int x, int y) {
return Integer.bitCount(x ^ y);
}
3.颠倒二进制位
190. 颠倒二进制位
一开始尝试字符串解法出问题了,还是老老实实用位运算好。位运算的括号很重要,别省略掉。
// public int reverseBits(int n) {
// String str = Integer.toBinaryString(n);
// char[] ca = str.toCharArray();
// int i = 0, j = str.length() - 1;
// while(i < j) {
// char tmp = ca[i];
// ca[i++] = ca[j];
// ca[j--] = tmp;
// }
// return Integer.parseInt(new String(ca));
// }
public int reverseBits(int n) {
int ret = 0, len = 31;
while (n != 0) {
ret += (n & 1) << len--;
n >>>= 1;
}
return ret;
}
4.数字范围按位与
法1:布赖恩·克尼根算法
这个算法很有用,必须好好理解掌握。一般用while循环。
public int rangeBitwiseAnd(int m, int n) {
while (m < n) {
n &= n - 1;
}
return n;
}
5.只出现一次的数字
136.只出现一次的数字
a ^ a = 0
0 ^ a = a
// public int singleNumber(int[] nums) {
// Set<Integer> set = new HashSet<>();
// for (int i : nums) {
// if (!set.add(i)) {
// set.remove(i);
// }
// }
// return set.iterator().next();
// }
public int singleNumber(int[] nums) {
int res = 0;
for (int num : nums) {
res ^= num;
}
return res;
}
6.丢失的数字
268.丢失的数字
法1:哈希表
public int missingNumber(int[] nums) {
Set<Integer> set = new HashSet<>();
for (int i = 0; i <= nums.length; i++)
set.add(i);
for (int num : nums)
set.remove(num);
return set.iterator().next();
}
法2:位运算
public int missingNumber(int[] nums) {
int ret = nums.length;
for (int i = 0; i < nums.length; i++) {
ret ^= i ^ nums[i];
}
return ret;
}
7.比特位计数
338.比特位计数
可以理解成在第1题上加个for循环。
public int[] countBits(int num) {
int[] nums = new int[num + 1];
for (int i = 1; i < nums.length; i++) {
int n = i, count = 0;
while (n != 0) {
n &= n - 1;
count++;
}
nums[i] = count;
}
return nums;
}