位运算
文章目录
- 位运算
- LeetCode 231. Power of Two
- LeetCode 762. Prime Number of Set Bits in Binary Representation
- LeetCode 136. Single Number
- LeetCode 476. Number Complement
- LeetCode 137. Single Number II
- LeetCode 260. Single Number III
- LeetCode 371. Sum of Two Integers
- LeetCode 201. Bitwise AND of Numbers Range
- LeetCode 477. Total Hamming Distance
- LeetCode 421. Maximum XOR of Two Numbers in an Array
LeetCode 231. Power of Two
class Solution {
public:
bool isPowerOfTwo(int n) {
return n>0 && (1 << 30)%n == 0;
//return (n>0 && (n & -n) == n);
}
};
//lowbit,取出n二进制中第一个1的位置k
/*
lowbit(n) = n & ( ~ n + 1 )
又在补码中,~n+1= - n,所以
lowbit(n) = n & (- n)
那lowbit有什么应用呢?我们可以求得一个数字二进制中所有1的个数,从而得到0的个数……
https://www.cnblogs.com/CuteAbacus/p/9464358.html
*/
LeetCode 762. Prime Number of Set Bits in Binary Representation
class Solution {
public:
int countPrimeSetBits(int L, int R) {
unordered_set<int> primes({2,3,5,7,11,13,17,19});
int res = 0;
for(int i = L; i <= R; i++)
{
int s = 0;
int k = i;
while(k)
{
s += k & 1;
k >>= 1;
}
if(primes.count(s))
res++;
}
return res;
}
};
//判断1的个数
LeetCode 136. Single Number
class Solution {
public:
int singleNumber(vector<int>& nums) {
if(nums.size() == 0)return 0;
int res = nums[0];
for(int i = 1; i < nums.size(); i++)
{
res ^= nums[i];
}
return res;
}
};
//异或的性质,但是如果留下两个呢?
LeetCode 476. Number Complement
class Solution {
public:
int findComplement(int num) {
int res = 0;
int t = 0;
while(num)
{
res += (!(num & 1)) << t;
num >>= 1;
t++;
}
return res;
}
};
//取1
LeetCode 137. Single Number II
class Solution {
public:
int singleNumber(vector<int>& nums) {
//方法一:
// int ans = 0;
// for(int i = 0; i < 32; i++)
// {
// int count = 0;
// for(int j = 0; j < nums.size(); j++)
// {
// count += nums[j] >> i & 1;
// }
// ans += (count%3) << i;
// }
// return ans;
//神仙做法:
//状态机,初始为0,0
//1个1, 1 0; 2个1, 0 1; 3个1, 0 0
int ones = 0, twos = 0;
for(auto x : nums)
{
ones = (ones ^ x) & ~twos;
twos = (twos ^ x) & ~ones;
}
return ones;
}
};
LeetCode 260. Single Number III
class Solution {
public:
vector<int> singleNumber(vector<int>& nums) {
//得到两个数异或的结果
int s = 0;
for(auto x : nums) s ^= x;
//找到第k位,是不是可以用lowbit
int k = 0;
while(!(s >> k & 1))k++;
//分组异或
int s2 = 0;
for(auto x : nums)
{
if(x >> k & 1)
s2 ^= x;
}
int s3 = s ^ s2;
return vector<int>({s2, s3});
}
};
//这里用到了取最低位
LeetCode 371. Sum of Two Integers
class Solution {
public:
int getSum(int a, int b) {
if(!b)return a;
int sum = a ^ b;
unsigned int carry = (unsigned int)(a & b) << 1;
return getSum(sum, carry);
}
};
//carry要是无符号整形,对负数有效
LeetCode 201. Bitwise AND of Numbers Range
class Solution {
public:
int rangeBitwiseAnd(int m, int n) {
int res = 0;
for(int i = 0; (1ll << i) <= m; i++)
{
if(m >> i & 1)
{
if((m & ~((1<<i)-1ll)) + (1 << i) > n )
res += 1 << i;
}
}
return res;
}
};
//这题没看懂
LeetCode 477. Total Hamming Distance
class Solution {
public:
int totalHammingDistance(vector<int>& nums) {
int res = 0;
for(int i = 0; i <= 30; i++)
{
int ones = 0;
for(auto x : nums)
{
if(x >> i & 1)
ones++;
}
res += ones * (nums.size() - ones);
}
return res;
}
};
//这题关键是巧妙的汉明距离,变成了某一个1个个数和0的个数的乘积
LeetCode 421. Maximum XOR of Two Numbers in an Array
class Solution {
public:
struct Node
{
int son[2];
};
vector<Node> nodes;
int findMaximumXOR(vector<int>& nums) {
nodes.push_back(Node({0,0}));
for(auto x : nums)
{
int p = 0;
for(int i = 30; i >= 0; i--)
{
int t = x >> i & 1;
if(!nodes[p].son[t])
{
nodes.push_back(Node{0,0});
nodes[p].son[t] = nodes.size() - 1;
}
p = nodes[p].son[t];
}
}
int res = 0;
for(auto x : nums)
{
int p = 0, XOR = 0;
for(int i = 30; i >= 0; i--)
{
int t = x >> i & 1;
if(nodes[p].son[!t])
{
p = nodes[p].son[!t];
XOR += 1 << i;
}
else
{
p = nodes[p].son[t];
}
}
res = max(res, XOR);
}
return res;
}
};
//关键建立一个trie树,然后从最高位开始找不同
来源:CSDN
作者:zc_zhao
链接:https://blog.csdn.net/zhaozhichenghpu/article/details/103774238