461. 汉明距离
俩写法。
位运算。先异或,不同的就为1 。在循环与 &1,看有多少不同。每次右移直到数据用完。
class Solution {
public:
int hammingDistance(int x, int y)
{
int diff = x ^ y;
int ans = 0;
while(diff)
{
ans += diff & 1;
diff >>= 1;
}
return ans;
}
};
还有就是直接用库函数
class Solution
{
public:
int hammingDistance(int x, int y)
{
return __builtin_popcount(x^y);
}
};
190. 颠倒二进制位
好轮子,可以记一下。
class Solution {
public:
uint32_t reverseBits(uint32_t n)
{
int ans = 0;
for(int i = 0;i < 32;i++)
{
ans <<= 1;//每次左移给低位补零
ans += n & 1;//从最后一个数开始,如是1则ans + 1,10 -> 11
//反之还是0,实现颠倒
n >>= 1;//n低位舍掉
}
return ans;
}
};
136. 只出现一次的数字
真的想不到,大佬真是大佬,可以记一下。位运算真是巧妙
class Solution {
public:
int singleNumber(vector<int>& nums)
{
int ans = 0;
for(int num : nums)
{
ans ^= num;
}
如果只出现一次 x ^ 0 = x,两次的话又变回了0 ;x ^ x = 0
return ans;
}
};
342. 4的幂
一个四次幂,也必定是二次幂。先判断是否是二次幂。
! ( n & (n - 1) )
在看四次幂,比如4,二进制是 100,1的位置都在偶数上,那么 n & 10101…101 ! = 0 。 偶数上的1 & 1 = 1,奇数上的0 & 0 = 0
318. 最大单词长度乘积
有点难啊。上代码分析
class Solution {
public:
int maxProduct(vector<string>& words)
{
int n = words.size();
unordered_map<int,int> hash;//哈希表
int ans = 0;
for(auto word : words)
{
int size = word.size(),mask = 0;
for(auto ch : word)
{
mask = mask | (1 << ch - 'a');
这一步把每个位置上有字符的为1,无字符的为0.如,ab = 11,ac = 101.bd = 1010
从后往前看。这里mask仅仅是与最后一位进行了或运算
}
hash[mask] = max(size,hash[mask]);
这里更新每个mask的哈希值,但是不能直接写 hash[mask] = size;
题目虽然要求两个字符串直接不可以有重复字符,但是一个字符串内会有重复的。
aa = a = 1,但是哈希值要去长度更长的2,所以要不断比较max
for(auto [h_mask,h_len] : hash)遍历比较
{
if(! (mask & h_mask))判断是否有相同字符
{
ans = max(ans,size * h_len);
}
}
}
return ans;
}
};
338. 比特位计数
位运算和动规俩写法。
位运算:
class Solution {
public:
vector<int> countBits(int n)
{
vector<int> ans;
for(int i = 0;i <= n;i++)
{
int res = 0;
int t = i;
while(t)
{
res += t & 1;
t >>= 1;
}
ans.push_back(res);
}
return ans;
}
};
动规:
class Solution {
public:
vector<int> countBits(int n)
{
vector<int> 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. 丢失的数字
写出来了。与正确的数据异或一次,再与给出的数据异或一次返回。
0 ^ x = x;
0 ^ x ^ x =0;
693. 交替位二进制数
错位异或
476. 数字的补数
异或真滴强。异或,同为0不同为1,将Nums与全1数据异或,原来的0变成1,1变成0。
所以需要知道nums有几位,得到一个全1,nums.size()位的数据。
复制一个tmp = num,tmp每次右移直到tmp < 0,,res 每次左移 +1,最后res就是全1,nums.size()位的数据。与num异或即可。
260 见剑指offer 56-I