x ^ 0s = x x & 0s = 0 x | 0s = x
x ^ 1s = ~x x & 1s = x x | 1s = 1s
x ^ x = 0 x & x = x x | x = x
461. 汉明距离
461. Hamming Distance
两个整数之间的 汉明距离 指的是这两个数字对应二进制位不同的位置的数目。
给你两个整数 x
和 y
,计算并返回它们之间的汉明距离。
对两个数进行按位异或操作,统计有多少个 1 即可。
class Solution {
public:
int hammingDistance(int x, int y) {
int diff = x ^ y, ans = 0;
while(diff){
ans += diff & 1;
diff >>= 1;
}
return ans;
}
};
190. 颠倒二进制位
190. Reverse Bits
颠倒给定的 32 位无符号整数的二进制位。
提示:
请注意,在某些语言(如 Java)中,没有无符号整数类型。在这种情况下,输入和输出都将被指定为有符号整数类型,并且不应影响您的实现,因为无论整数是有符号的还是无符号的,其内部的二进制表示形式都是相同的。
在 Java 中,编译器使用二进制补码记法来表示有符号整数。因此,在 示例 2 中,输入表示有符号整数 -3,输出表示有符号整数 -1073741825。
使用算术左移和右移,可以很轻易地实现二进制的翻转。
class Solution {
public:
uint32_t reverseBits(uint32_t n) {
uint32_t ans = 0;
for(int i=0; i<32; ++i){
// ans左移一位留出位置
ans <<= 1;
// 将n的最后一位放到ans留出的末尾
ans += n & 1;
// 将n最后一位移出
n >>= 1;
}
return ans;
}
};
136. 只出现一次的数字
136. Single Number
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
我们可以利用 x ∧ x = 0 和 x ∧ 0 = x 的特点,将数组内所有的数字进行按位异或。出现两次 的所有数字按位异或的结果是 0 , 0 与出现一次的数字异或可以得到这个数字本身。
class Solution {
public:
int singleNumber(vector& nums) {
int ans = 0;
for(const int & num: nums){
ans ^= num;
}
return ans;
}
};
342. 4的幂
342. Power of Four
给定一个整数,写一个函数来判断它是否是 4 的幂次方。如果是,返回 true ;否则,返回 false 。
整数 n 是 4 的幂次方需满足:存在整数 x 使得 n == 4^x
首先我们考虑一个数字是不是 2 的(整数)次方:如果一个数字 n 是 2 的整数次方,那么它的二进制一定是 0...010...0 这样的形式;考虑到 n − 1 的二进制是 0...001...1,这两个数求按位与的结果一定是 0。因此如果 n & (n - 1) 为 0,那么这个数是 2 的次方。
如果这个数也是 4 的次方,那二进制表示中 1 的位置必须为奇数位。我们可以把 n 和二进制的 10101...101 (即十进制下的 1431655765 )做按位与,如果结果不为 0 ,那么说明这个数是 4 的次方。
class Solution {
public:
bool isPowerOfFour(int n) {
return n > 0 && !(n & n - 1) && (n & 1431655765);
}
};
318. 最大单词长度乘积
318. Maximum Product of Word Lengths
给你一个字符串数组 words ,找出并返回 length(words[i]) * length(words[j]) 的最大值,并且这两个单词不含有公共字母。如果不存在这样的两个单词,返回 0 。
怎样快速判断两个字母串是否含有重复数字呢?可以为每个字母串建立一个长度为 26 的二进制数字,每个位置表示是否存在该字母。如果两个字母串含有重复数字,那它们的二进制表示的按位与不为 0 。同时,我们可以建立一个哈希表来存储字母串(在数组的位置)到二进制数字的映射关系,方便查找调用。
class Solution {
public:
int maxProduct(vector& words) {
unordered_map hash;
int ans = 0;
for(const string & word: words){
int mask = 0, size = word.size();
for(const char & c: word){
mask |= 1 << (c - 'a');
}
hash[mask] = max(hash[mask], size);
for(const auto & [h_mask, h_len]: hash){
if(!(mask & h_mask)){
ans = max(ans, size * h_len);
}
}
}
return ans;
}
};
338. 比特位计数
338. Counting Bits
给你一个整数 n
,对于 0 <= i <= n
中的每个 i
,计算其二进制表示中 1
的个数 ,返回一个长度为 n + 1
的数组 ans
作为答案。
本题可以利用动态规划和位运算进行快速的求解。定义一个数组 dp ,其中 dp[i] 表示数字 i 的二进制含有 1 的个数。对于第 i 个数字,如果它二进制的最后一位为 1 ,那么它含有 1 的个数 则为 dp[i-1] + 1 ;如果它二进制的最后一位为 0 ,那么它含有 1 的个数和其算术右移结果相同,即 dp[i>> 1] 。
class Solution {
public:
vector countBits(int n) {
vector dp(n + 1, 0);
for(int i=1; i<=n; ++i){
dp[i] = i & 1? dp[i - 1] + 1: dp[i>>1];
}
return dp;
}
};
268. 丢失的数字
268. Missing Number
693. 交替位二进制数
693. Binary Number with Alternating Bits
476. 数字的补数
476. Number Complement
260. 只出现一次的数字 III
260. Single Number III
欢迎大家共同学习和纠正指教