题目列表源于:acwing
题目源于leetcode
给你两个整数 left 和 right ,在闭区间 [left, right] 范围内,统计并返回 计算置位位数为质数 的整数个数。
计算置位位数 就是二进制表示中 1 的个数。
例如, 21 的二进制表示 10101 有 3 个计算置位
数字中包含二进制中1的个数,采取lowbit方式进行实现,其运算一个数据的实践复杂度为O(m), m为数字中包含1的个数,然后通过数字标记素数的形式判断是否是素数,这么做会多占用一些空间,因为数据量比较小,大概20个左右的数据,因此可以采取二进制的形式对其进行标记,mask=665772=10100010100010101100。
class Solution {
public:
int lowbit(int x){return x&(-x);}
int bit_num(int x){
int bt = 0;
while(x){
bt++;
x -= lowbit(x);
}
return bt;
}
int countPrimeSetBits(int left, int right) {
int cn = 0;
for(int i = left; i <= right; i++){
// cout<
if((1<<bit_num(i))&665772)cn++;
}
return cn;
}
};
// 1 10 11
// 100 101 110
// 111 1000 1001
// 1010
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
由于异或有个性质 a ^ a = 0,所有出现两次的数据,直接相互抵消,所以只需要遍历一次即可将所有出现两次的数据剔除,只剩下出现一次的数据。
class Solution {
public:
int singleNumber(vector<int>& nums) {
int ans = 0;
for(int i = 0; i < nums.size(); i++){
ans ^= nums[i];
}
return ans;
}
};
给你一个整数数组 nums ,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次 。请你找出并返回那个只出现了一次的元素。
类似于二进制的形式,这里采取三进制的形式,将数据拆成二进制的形式,相应位置为3个的时候则表明数据出现过三次。
class Solution {
public:
int singleNumber(vector<int>& nums) {
int ans = 0;
for(int i = 0; i < 32; i++){
int tot = 0;
for(auto num: nums){
tot += (num>>i)&1;
}
if(tot % 3)ans |= (1<<i);
}
return ans;
}
};
给定一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。你可以按 任意顺序 返回答案。
因为只包含一个可以遍历一遍求出,所以将其进行分组,分成两组,遍历一遍将其求出,如何分组呢,先异或遍历一遍所有的数据,当某位数为1,则表明这位数,仅剩的两个数在这位不同,因此根据这里的数据是1还是0进行区分。
class Solution {
public:
long lowbit(long x){return x&(-x);}
vector<int> singleNumber(vector<int>& nums) {
int ans = 0;
for(int i = 0; i < nums.size(); i++)ans ^= nums[i];
int kind = lowbit(ans);
long a = 0, b = 0;
for(int i = 0; i < nums.size(); i++){
if(nums[i]& kind){
a ^= nums[i];
}
else b ^= nums[i];
}
vector<int>res;
res.push_back(a);
res.push_back(b);
return res;
}
};
给你两个整数 left 和 right ,表示区间 [left, right] ,返回此区间内所有数字 按位与 的结果(包含 left 、right 端点)。
最直观的想法是获取left,最低为的1位置,然后对其进行加1,观察其与之right之间的关系,超过right则保留,不超过right则置为0,进行累计。
class Solution {
public:
long lowbit(long x){return x&(-x);}
int rangeBitwiseAnd(int left, int right) {
int ans = 0;
long n = left, m = right;
while(n){
int bit = lowbit(n);
if(n+bit > m)ans += bit;
n -= bit;
}
return ans;
}
};
两个整数的 汉明距离 指的是这两个数字的二进制数对应位不同的数量。
给你一个整数数组 nums,请你计算并返回 nums 中任意两个数之间 汉明距离的总和 。
统计二进制相应位置1的个数c,然后乘以(n-c),进行累加。
class Solution {
public:
int totalHammingDistance(vector<int>& nums) {
int sum = 0;
for(int i = 0; i < 31; i++){
int cn = 0 ;
for(auto num: nums){
if(num&(1<<i))cn++;
}
sum += (nums.size()-cn)*cn;
}
return sum;
}
};