差了4天会补上的
面试题 16.01 交换数字
解题思路
我们只需要知道最基本的公式就是,当两个相同的数进行异或时,结果为0,即a^a为0,a = a^b如果想得到a为b只需要在此基础上再异或一个a即可。
代码
class Solution {
public:
vector<int> swapNumbers(vector<int>& numbers) {
numbers[0] ^= numbers[1];//a^b
numbers[1] ^= numbers[0];//b = a ^ b ^ b->b = a
numbers[0] ^= numbers[1];//a = a ^ b ^ a->a = b
return numbers;
}
};
1342 将数字变成0的操作次数
解题思路
按步骤计算即可。可参考注释
要注意奇数和偶数的位运算判断。
代码
class Solution {
public:
int numberOfSteps(int num) {
int ret = 0;
while (num) {
//当num为1时,既是奇数但减一后为0,只有 1步,所以要单独讨论。
ret += (num > 1 ? 1 : 0) + (num & 0x01);//如果是奇数,那么减一算一步,除以二再算一步。
num >>= 1;
}
return ret;
}
};
476 数字的补数
解题思路
我们需要注意二进制最高位0表示正,1表示负数。
对于此题,我们只要知道这个数的二进制位数即可通过与相同位数的二进制位全1整数进行异或即可。
代码
class Solution {
public:
int findComplement(int num) {
//想要知道这个数在二进制中是多少位的。
int highbit = 0;
for(int i = 1;i<= 30;i++){
if(num >= (1 << i)){
highbit = i;
}
else {
break;
}
}
//注意当highbit等于30时,即将(hightbit+1->31)1左移31位,共32位,值为2**31,再减一就是int在正数部分的最大值。但这样会让符号位为1导致变负数,所以得单独讨论,用首位为0其余为1.和num进行异或.
int mask = (highbit == 30?0x7FFFFFFF:(1 << (highbit + 1)) - 1);
return num ^ mask;
}
};
2044 统计按位或能得到最大值的子集数目
解题思路
二进制i中存储这对n个数的选取情况,选完之后还要再循环找回去第几个数被选中,即nums[j]被选中。
代码
class Solution {
public:
int countMaxOrSubsets(vector<int>& nums) {
/*
1.最多有2**nums.size()-1个非空子集。
2.或:都为0时才为0其余为1.
*/
int n = nums.size(), maxValue = 0, cnt = 0, stateNumber = 1 << n;
for(int i = 0;i<nums.size();i++)
maxValue |= nums[i];
for (int i = 0; i < stateNumber; i++) {
int cur = 0;//因为stateNumber-1为选中集合中所有元素所以cur就不用赋为0了。
for (int j = 0; j < n; j++) {
if (((i >> j) & 1) == 1) {
cur |= nums[j];
}
}
if(cur == maxValue){
cnt++;
}
// if (cur == maxValue) {
// cnt++;
// } else if (cur > maxValue) {//不断让maxValue变大,最终整个集合的或是最大的。或起来只会大于等于原来两个数,不会变小。找到后cnt为1即可。
// maxValue = cur;
// cnt = 1;
// }
}
return cnt;
}
};